]> Git Repo - qemu.git/blob - hw/audio/hda-codec.c
audio/hda: tweak timer adjust logic
[qemu.git] / hw / audio / hda-codec.c
1 /*
2  * Copyright (C) 2010 Red Hat, Inc.
3  *
4  * written by Gerd Hoffmann <[email protected]>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 or
9  * (at your option) version 3 of the License.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include "qemu/osdep.h"
21 #include "qemu/atomic.h"
22 #include "hw/hw.h"
23 #include "hw/pci/pci.h"
24 #include "intel-hda.h"
25 #include "intel-hda-defs.h"
26 #include "audio/audio.h"
27 #include "trace.h"
28
29 /* -------------------------------------------------------------------------- */
30
31 typedef struct desc_param {
32     uint32_t id;
33     uint32_t val;
34 } desc_param;
35
36 typedef struct desc_node {
37     uint32_t nid;
38     const char *name;
39     const desc_param *params;
40     uint32_t nparams;
41     uint32_t config;
42     uint32_t pinctl;
43     uint32_t *conn;
44     uint32_t stindex;
45 } desc_node;
46
47 typedef struct desc_codec {
48     const char *name;
49     uint32_t iid;
50     const desc_node *nodes;
51     uint32_t nnodes;
52 } desc_codec;
53
54 static const desc_param* hda_codec_find_param(const desc_node *node, uint32_t id)
55 {
56     int i;
57
58     for (i = 0; i < node->nparams; i++) {
59         if (node->params[i].id == id) {
60             return &node->params[i];
61         }
62     }
63     return NULL;
64 }
65
66 static const desc_node* hda_codec_find_node(const desc_codec *codec, uint32_t nid)
67 {
68     int i;
69
70     for (i = 0; i < codec->nnodes; i++) {
71         if (codec->nodes[i].nid == nid) {
72             return &codec->nodes[i];
73         }
74     }
75     return NULL;
76 }
77
78 static void hda_codec_parse_fmt(uint32_t format, struct audsettings *as)
79 {
80     if (format & AC_FMT_TYPE_NON_PCM) {
81         return;
82     }
83
84     as->freq = (format & AC_FMT_BASE_44K) ? 44100 : 48000;
85
86     switch ((format & AC_FMT_MULT_MASK) >> AC_FMT_MULT_SHIFT) {
87     case 1: as->freq *= 2; break;
88     case 2: as->freq *= 3; break;
89     case 3: as->freq *= 4; break;
90     }
91
92     switch ((format & AC_FMT_DIV_MASK) >> AC_FMT_DIV_SHIFT) {
93     case 1: as->freq /= 2; break;
94     case 2: as->freq /= 3; break;
95     case 3: as->freq /= 4; break;
96     case 4: as->freq /= 5; break;
97     case 5: as->freq /= 6; break;
98     case 6: as->freq /= 7; break;
99     case 7: as->freq /= 8; break;
100     }
101
102     switch (format & AC_FMT_BITS_MASK) {
103     case AC_FMT_BITS_8:  as->fmt = AUD_FMT_S8;  break;
104     case AC_FMT_BITS_16: as->fmt = AUD_FMT_S16; break;
105     case AC_FMT_BITS_32: as->fmt = AUD_FMT_S32; break;
106     }
107
108     as->nchannels = ((format & AC_FMT_CHAN_MASK) >> AC_FMT_CHAN_SHIFT) + 1;
109 }
110
111 /* -------------------------------------------------------------------------- */
112 /*
113  * HDA codec descriptions
114  */
115
116 /* some defines */
117
118 #define QEMU_HDA_ID_VENDOR  0x1af4
119 #define QEMU_HDA_PCM_FORMATS (AC_SUPPCM_BITS_16 |       \
120                               0x1fc /* 16 -> 96 kHz */)
121 #define QEMU_HDA_AMP_NONE    (0)
122 #define QEMU_HDA_AMP_STEPS   0x4a
123
124 #define   PARAM mixemu
125 #define   HDA_MIXER
126 #include "hda-codec-common.h"
127
128 #define   PARAM nomixemu
129 #include  "hda-codec-common.h"
130
131 #define HDA_TIMER_TICKS (SCALE_MS)
132 #define B_SIZE sizeof(st->buf)
133 #define B_MASK (sizeof(st->buf) - 1)
134
135 /* -------------------------------------------------------------------------- */
136
137 static const char *fmt2name[] = {
138     [ AUD_FMT_U8  ] = "PCM-U8",
139     [ AUD_FMT_S8  ] = "PCM-S8",
140     [ AUD_FMT_U16 ] = "PCM-U16",
141     [ AUD_FMT_S16 ] = "PCM-S16",
142     [ AUD_FMT_U32 ] = "PCM-U32",
143     [ AUD_FMT_S32 ] = "PCM-S32",
144 };
145
146 typedef struct HDAAudioState HDAAudioState;
147 typedef struct HDAAudioStream HDAAudioStream;
148
149 struct HDAAudioStream {
150     HDAAudioState *state;
151     const desc_node *node;
152     bool output, running;
153     uint32_t stream;
154     uint32_t channel;
155     uint32_t format;
156     uint32_t gain_left, gain_right;
157     bool mute_left, mute_right;
158     struct audsettings as;
159     union {
160         SWVoiceIn *in;
161         SWVoiceOut *out;
162     } voice;
163     uint8_t compat_buf[HDA_BUFFER_SIZE];
164     uint32_t compat_bpos;
165     uint8_t buf[8192]; /* size must be power of two */
166     int64_t rpos;
167     int64_t wpos;
168     QEMUTimer *buft;
169     int64_t buft_start;
170 };
171
172 #define TYPE_HDA_AUDIO "hda-audio"
173 #define HDA_AUDIO(obj) OBJECT_CHECK(HDAAudioState, (obj), TYPE_HDA_AUDIO)
174
175 struct HDAAudioState {
176     HDACodecDevice hda;
177     const char *name;
178
179     QEMUSoundCard card;
180     const desc_codec *desc;
181     HDAAudioStream st[4];
182     bool running_compat[16];
183     bool running_real[2 * 16];
184
185     /* properties */
186     uint32_t debug;
187     bool     mixer;
188     bool     use_timer;
189 };
190
191 static inline int64_t hda_bytes_per_second(HDAAudioStream *st)
192 {
193     return 2 * st->as.nchannels * st->as.freq;
194 }
195
196 static inline void hda_timer_sync_adjust(HDAAudioStream *st, int64_t target_pos)
197 {
198     int64_t limit = B_SIZE / 8;
199     int64_t corr = 0;
200
201     if (target_pos > limit) {
202         corr = HDA_TIMER_TICKS;
203     }
204     if (target_pos < -limit) {
205         corr = -HDA_TIMER_TICKS;
206     }
207     if (corr == 0) {
208         return;
209     }
210
211     trace_hda_audio_adjust(st->node->name, target_pos);
212     atomic_fetch_add(&st->buft_start, corr);
213 }
214
215 static void hda_audio_input_timer(void *opaque)
216 {
217     HDAAudioStream *st = opaque;
218
219     int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
220
221     int64_t buft_start = atomic_fetch_add(&st->buft_start, 0);
222     int64_t wpos = atomic_fetch_add(&st->wpos, 0);
223     int64_t rpos = atomic_fetch_add(&st->rpos, 0);
224
225     int64_t wanted_rpos = hda_bytes_per_second(st) * (now - buft_start)
226                           / NANOSECONDS_PER_SECOND;
227     wanted_rpos &= -4; /* IMPORTANT! clip to frames */
228
229     if (wanted_rpos <= rpos) {
230         /* we already transmitted the data */
231         goto out_timer;
232     }
233
234     int64_t to_transfer = audio_MIN(wpos - rpos, wanted_rpos - rpos);
235     while (to_transfer) {
236         uint32_t start = (rpos & B_MASK);
237         uint32_t chunk = audio_MIN(B_SIZE - start, to_transfer);
238         int rc = hda_codec_xfer(
239                 &st->state->hda, st->stream, false, st->buf + start, chunk);
240         if (!rc) {
241             break;
242         }
243         rpos += chunk;
244         to_transfer -= chunk;
245         atomic_fetch_add(&st->rpos, chunk);
246     }
247
248 out_timer:
249
250     if (st->running) {
251         timer_mod_anticipate_ns(st->buft, now + HDA_TIMER_TICKS);
252     }
253 }
254
255 static void hda_audio_input_cb(void *opaque, int avail)
256 {
257     HDAAudioStream *st = opaque;
258
259     int64_t wpos = atomic_fetch_add(&st->wpos, 0);
260     int64_t rpos = atomic_fetch_add(&st->rpos, 0);
261
262     int64_t to_transfer = audio_MIN(B_SIZE - (wpos - rpos), avail);
263
264     hda_timer_sync_adjust(st, -((wpos - rpos) + to_transfer - (B_SIZE >> 1)));
265
266     while (to_transfer) {
267         uint32_t start = (uint32_t) (wpos & B_MASK);
268         uint32_t chunk = (uint32_t) audio_MIN(B_SIZE - start, to_transfer);
269         uint32_t read = AUD_read(st->voice.in, st->buf + start, chunk);
270         wpos += read;
271         to_transfer -= read;
272         atomic_fetch_add(&st->wpos, read);
273         if (chunk != read) {
274             break;
275         }
276     }
277 }
278
279 static void hda_audio_output_timer(void *opaque)
280 {
281     HDAAudioStream *st = opaque;
282
283     int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
284
285     int64_t buft_start = atomic_fetch_add(&st->buft_start, 0);
286     int64_t wpos = atomic_fetch_add(&st->wpos, 0);
287     int64_t rpos = atomic_fetch_add(&st->rpos, 0);
288
289     int64_t wanted_wpos = hda_bytes_per_second(st) * (now - buft_start)
290                           / NANOSECONDS_PER_SECOND;
291     wanted_wpos &= -4; /* IMPORTANT! clip to frames */
292
293     if (wanted_wpos <= wpos) {
294         /* we already received the data */
295         goto out_timer;
296     }
297
298     int64_t to_transfer = audio_MIN(B_SIZE - (wpos - rpos), wanted_wpos - wpos);
299     while (to_transfer) {
300         uint32_t start = (wpos & B_MASK);
301         uint32_t chunk = audio_MIN(B_SIZE - start, to_transfer);
302         int rc = hda_codec_xfer(
303                 &st->state->hda, st->stream, true, st->buf + start, chunk);
304         if (!rc) {
305             break;
306         }
307         wpos += chunk;
308         to_transfer -= chunk;
309         atomic_fetch_add(&st->wpos, chunk);
310     }
311
312 out_timer:
313
314     if (st->running) {
315         timer_mod_anticipate_ns(st->buft, now + HDA_TIMER_TICKS);
316     }
317 }
318
319 static void hda_audio_output_cb(void *opaque, int avail)
320 {
321     HDAAudioStream *st = opaque;
322
323     int64_t wpos = atomic_fetch_add(&st->wpos, 0);
324     int64_t rpos = atomic_fetch_add(&st->rpos, 0);
325
326     int64_t to_transfer = audio_MIN(wpos - rpos, avail);
327
328     hda_timer_sync_adjust(st, (wpos - rpos) - to_transfer - (B_SIZE >> 1));
329
330     while (to_transfer) {
331         uint32_t start = (uint32_t) (rpos & B_MASK);
332         uint32_t chunk = (uint32_t) audio_MIN(B_SIZE - start, to_transfer);
333         uint32_t written = AUD_write(st->voice.out, st->buf + start, chunk);
334         rpos += written;
335         to_transfer -= written;
336         atomic_fetch_add(&st->rpos, written);
337         if (chunk != written) {
338             break;
339         }
340     }
341 }
342
343 static void hda_audio_compat_input_cb(void *opaque, int avail)
344 {
345     HDAAudioStream *st = opaque;
346     int recv = 0;
347     int len;
348     bool rc;
349
350     while (avail - recv >= sizeof(st->compat_buf)) {
351         if (st->compat_bpos != sizeof(st->compat_buf)) {
352             len = AUD_read(st->voice.in, st->compat_buf + st->compat_bpos,
353                            sizeof(st->compat_buf) - st->compat_bpos);
354             st->compat_bpos += len;
355             recv += len;
356             if (st->compat_bpos != sizeof(st->compat_buf)) {
357                 break;
358             }
359         }
360         rc = hda_codec_xfer(&st->state->hda, st->stream, false,
361                             st->compat_buf, sizeof(st->compat_buf));
362         if (!rc) {
363             break;
364         }
365         st->compat_bpos = 0;
366     }
367 }
368
369 static void hda_audio_compat_output_cb(void *opaque, int avail)
370 {
371     HDAAudioStream *st = opaque;
372     int sent = 0;
373     int len;
374     bool rc;
375
376     while (avail - sent >= sizeof(st->compat_buf)) {
377         if (st->compat_bpos == sizeof(st->compat_buf)) {
378             rc = hda_codec_xfer(&st->state->hda, st->stream, true,
379                                 st->compat_buf, sizeof(st->compat_buf));
380             if (!rc) {
381                 break;
382             }
383             st->compat_bpos = 0;
384         }
385         len = AUD_write(st->voice.out, st->compat_buf + st->compat_bpos,
386                         sizeof(st->compat_buf) - st->compat_bpos);
387         st->compat_bpos += len;
388         sent += len;
389         if (st->compat_bpos != sizeof(st->compat_buf)) {
390             break;
391         }
392     }
393 }
394
395 static void hda_audio_set_running(HDAAudioStream *st, bool running)
396 {
397     if (st->node == NULL) {
398         return;
399     }
400     if (st->running == running) {
401         return;
402     }
403     st->running = running;
404     trace_hda_audio_running(st->node->name, st->stream, st->running);
405     if (st->state->use_timer) {
406         if (running) {
407             int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
408             st->rpos = 0;
409             st->wpos = 0;
410             st->buft_start = now;
411             timer_mod_anticipate_ns(st->buft, now + HDA_TIMER_TICKS);
412         } else {
413             timer_del(st->buft);
414         }
415     }
416     if (st->output) {
417         AUD_set_active_out(st->voice.out, st->running);
418     } else {
419         AUD_set_active_in(st->voice.in, st->running);
420     }
421 }
422
423 static void hda_audio_set_amp(HDAAudioStream *st)
424 {
425     bool muted;
426     uint32_t left, right;
427
428     if (st->node == NULL) {
429         return;
430     }
431
432     muted = st->mute_left && st->mute_right;
433     left  = st->mute_left  ? 0 : st->gain_left;
434     right = st->mute_right ? 0 : st->gain_right;
435
436     left = left * 255 / QEMU_HDA_AMP_STEPS;
437     right = right * 255 / QEMU_HDA_AMP_STEPS;
438
439     if (!st->state->mixer) {
440         return;
441     }
442     if (st->output) {
443         AUD_set_volume_out(st->voice.out, muted, left, right);
444     } else {
445         AUD_set_volume_in(st->voice.in, muted, left, right);
446     }
447 }
448
449 static void hda_audio_setup(HDAAudioStream *st)
450 {
451     bool use_timer = st->state->use_timer;
452     audio_callback_fn cb;
453
454     if (st->node == NULL) {
455         return;
456     }
457
458     trace_hda_audio_format(st->node->name, st->as.nchannels,
459                            fmt2name[st->as.fmt], st->as.freq);
460
461     if (st->output) {
462         if (use_timer) {
463             cb = hda_audio_output_cb;
464             st->buft = timer_new_ns(QEMU_CLOCK_VIRTUAL,
465                                     hda_audio_output_timer, st);
466         } else {
467             cb = hda_audio_compat_output_cb;
468         }
469         st->voice.out = AUD_open_out(&st->state->card, st->voice.out,
470                                      st->node->name, st, cb, &st->as);
471     } else {
472         if (use_timer) {
473             cb = hda_audio_input_cb;
474             st->buft = timer_new_ns(QEMU_CLOCK_VIRTUAL,
475                                     hda_audio_input_timer, st);
476         } else {
477             cb = hda_audio_compat_input_cb;
478         }
479         st->voice.in = AUD_open_in(&st->state->card, st->voice.in,
480                                    st->node->name, st, cb, &st->as);
481     }
482 }
483
484 static void hda_audio_command(HDACodecDevice *hda, uint32_t nid, uint32_t data)
485 {
486     HDAAudioState *a = HDA_AUDIO(hda);
487     HDAAudioStream *st;
488     const desc_node *node = NULL;
489     const desc_param *param;
490     uint32_t verb, payload, response, count, shift;
491
492     if ((data & 0x70000) == 0x70000) {
493         /* 12/8 id/payload */
494         verb = (data >> 8) & 0xfff;
495         payload = data & 0x00ff;
496     } else {
497         /* 4/16 id/payload */
498         verb = (data >> 8) & 0xf00;
499         payload = data & 0xffff;
500     }
501
502     node = hda_codec_find_node(a->desc, nid);
503     if (node == NULL) {
504         goto fail;
505     }
506     dprint(a, 2, "%s: nid %d (%s), verb 0x%x, payload 0x%x\n",
507            __func__, nid, node->name, verb, payload);
508
509     switch (verb) {
510     /* all nodes */
511     case AC_VERB_PARAMETERS:
512         param = hda_codec_find_param(node, payload);
513         if (param == NULL) {
514             goto fail;
515         }
516         hda_codec_response(hda, true, param->val);
517         break;
518     case AC_VERB_GET_SUBSYSTEM_ID:
519         hda_codec_response(hda, true, a->desc->iid);
520         break;
521
522     /* all functions */
523     case AC_VERB_GET_CONNECT_LIST:
524         param = hda_codec_find_param(node, AC_PAR_CONNLIST_LEN);
525         count = param ? param->val : 0;
526         response = 0;
527         shift = 0;
528         while (payload < count && shift < 32) {
529             response |= node->conn[payload] << shift;
530             payload++;
531             shift += 8;
532         }
533         hda_codec_response(hda, true, response);
534         break;
535
536     /* pin widget */
537     case AC_VERB_GET_CONFIG_DEFAULT:
538         hda_codec_response(hda, true, node->config);
539         break;
540     case AC_VERB_GET_PIN_WIDGET_CONTROL:
541         hda_codec_response(hda, true, node->pinctl);
542         break;
543     case AC_VERB_SET_PIN_WIDGET_CONTROL:
544         if (node->pinctl != payload) {
545             dprint(a, 1, "unhandled pin control bit\n");
546         }
547         hda_codec_response(hda, true, 0);
548         break;
549
550     /* audio in/out widget */
551     case AC_VERB_SET_CHANNEL_STREAMID:
552         st = a->st + node->stindex;
553         if (st->node == NULL) {
554             goto fail;
555         }
556         hda_audio_set_running(st, false);
557         st->stream = (payload >> 4) & 0x0f;
558         st->channel = payload & 0x0f;
559         dprint(a, 2, "%s: stream %d, channel %d\n",
560                st->node->name, st->stream, st->channel);
561         hda_audio_set_running(st, a->running_real[st->output * 16 + st->stream]);
562         hda_codec_response(hda, true, 0);
563         break;
564     case AC_VERB_GET_CONV:
565         st = a->st + node->stindex;
566         if (st->node == NULL) {
567             goto fail;
568         }
569         response = st->stream << 4 | st->channel;
570         hda_codec_response(hda, true, response);
571         break;
572     case AC_VERB_SET_STREAM_FORMAT:
573         st = a->st + node->stindex;
574         if (st->node == NULL) {
575             goto fail;
576         }
577         st->format = payload;
578         hda_codec_parse_fmt(st->format, &st->as);
579         hda_audio_setup(st);
580         hda_codec_response(hda, true, 0);
581         break;
582     case AC_VERB_GET_STREAM_FORMAT:
583         st = a->st + node->stindex;
584         if (st->node == NULL) {
585             goto fail;
586         }
587         hda_codec_response(hda, true, st->format);
588         break;
589     case AC_VERB_GET_AMP_GAIN_MUTE:
590         st = a->st + node->stindex;
591         if (st->node == NULL) {
592             goto fail;
593         }
594         if (payload & AC_AMP_GET_LEFT) {
595             response = st->gain_left | (st->mute_left ? AC_AMP_MUTE : 0);
596         } else {
597             response = st->gain_right | (st->mute_right ? AC_AMP_MUTE : 0);
598         }
599         hda_codec_response(hda, true, response);
600         break;
601     case AC_VERB_SET_AMP_GAIN_MUTE:
602         st = a->st + node->stindex;
603         if (st->node == NULL) {
604             goto fail;
605         }
606         dprint(a, 1, "amp (%s): %s%s%s%s index %d  gain %3d %s\n",
607                st->node->name,
608                (payload & AC_AMP_SET_OUTPUT) ? "o" : "-",
609                (payload & AC_AMP_SET_INPUT)  ? "i" : "-",
610                (payload & AC_AMP_SET_LEFT)   ? "l" : "-",
611                (payload & AC_AMP_SET_RIGHT)  ? "r" : "-",
612                (payload & AC_AMP_SET_INDEX) >> AC_AMP_SET_INDEX_SHIFT,
613                (payload & AC_AMP_GAIN),
614                (payload & AC_AMP_MUTE) ? "muted" : "");
615         if (payload & AC_AMP_SET_LEFT) {
616             st->gain_left = payload & AC_AMP_GAIN;
617             st->mute_left = payload & AC_AMP_MUTE;
618         }
619         if (payload & AC_AMP_SET_RIGHT) {
620             st->gain_right = payload & AC_AMP_GAIN;
621             st->mute_right = payload & AC_AMP_MUTE;
622         }
623         hda_audio_set_amp(st);
624         hda_codec_response(hda, true, 0);
625         break;
626
627     /* not supported */
628     case AC_VERB_SET_POWER_STATE:
629     case AC_VERB_GET_POWER_STATE:
630     case AC_VERB_GET_SDI_SELECT:
631         hda_codec_response(hda, true, 0);
632         break;
633     default:
634         goto fail;
635     }
636     return;
637
638 fail:
639     dprint(a, 1, "%s: not handled: nid %d (%s), verb 0x%x, payload 0x%x\n",
640            __func__, nid, node ? node->name : "?", verb, payload);
641     hda_codec_response(hda, true, 0);
642 }
643
644 static void hda_audio_stream(HDACodecDevice *hda, uint32_t stnr, bool running, bool output)
645 {
646     HDAAudioState *a = HDA_AUDIO(hda);
647     int s;
648
649     a->running_compat[stnr] = running;
650     a->running_real[output * 16 + stnr] = running;
651     for (s = 0; s < ARRAY_SIZE(a->st); s++) {
652         if (a->st[s].node == NULL) {
653             continue;
654         }
655         if (a->st[s].output != output) {
656             continue;
657         }
658         if (a->st[s].stream != stnr) {
659             continue;
660         }
661         hda_audio_set_running(&a->st[s], running);
662     }
663 }
664
665 static int hda_audio_init(HDACodecDevice *hda, const struct desc_codec *desc)
666 {
667     HDAAudioState *a = HDA_AUDIO(hda);
668     HDAAudioStream *st;
669     const desc_node *node;
670     const desc_param *param;
671     uint32_t i, type;
672
673     a->desc = desc;
674     a->name = object_get_typename(OBJECT(a));
675     dprint(a, 1, "%s: cad %d\n", __func__, a->hda.cad);
676
677     AUD_register_card("hda", &a->card);
678     for (i = 0; i < a->desc->nnodes; i++) {
679         node = a->desc->nodes + i;
680         param = hda_codec_find_param(node, AC_PAR_AUDIO_WIDGET_CAP);
681         if (param == NULL) {
682             continue;
683         }
684         type = (param->val & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
685         switch (type) {
686         case AC_WID_AUD_OUT:
687         case AC_WID_AUD_IN:
688             assert(node->stindex < ARRAY_SIZE(a->st));
689             st = a->st + node->stindex;
690             st->state = a;
691             st->node = node;
692             if (type == AC_WID_AUD_OUT) {
693                 /* unmute output by default */
694                 st->gain_left = QEMU_HDA_AMP_STEPS;
695                 st->gain_right = QEMU_HDA_AMP_STEPS;
696                 st->compat_bpos = sizeof(st->compat_buf);
697                 st->output = true;
698             } else {
699                 st->output = false;
700             }
701             st->format = AC_FMT_TYPE_PCM | AC_FMT_BITS_16 |
702                 (1 << AC_FMT_CHAN_SHIFT);
703             hda_codec_parse_fmt(st->format, &st->as);
704             hda_audio_setup(st);
705             break;
706         }
707     }
708     return 0;
709 }
710
711 static void hda_audio_exit(HDACodecDevice *hda)
712 {
713     HDAAudioState *a = HDA_AUDIO(hda);
714     HDAAudioStream *st;
715     int i;
716
717     dprint(a, 1, "%s\n", __func__);
718     for (i = 0; i < ARRAY_SIZE(a->st); i++) {
719         st = a->st + i;
720         if (st->node == NULL) {
721             continue;
722         }
723         if (a->use_timer) {
724             timer_del(st->buft);
725         }
726         if (st->output) {
727             AUD_close_out(&a->card, st->voice.out);
728         } else {
729             AUD_close_in(&a->card, st->voice.in);
730         }
731     }
732     AUD_remove_card(&a->card);
733 }
734
735 static int hda_audio_post_load(void *opaque, int version)
736 {
737     HDAAudioState *a = opaque;
738     HDAAudioStream *st;
739     int i;
740
741     dprint(a, 1, "%s\n", __func__);
742     if (version == 1) {
743         /* assume running_compat[] is for output streams */
744         for (i = 0; i < ARRAY_SIZE(a->running_compat); i++)
745             a->running_real[16 + i] = a->running_compat[i];
746     }
747
748     for (i = 0; i < ARRAY_SIZE(a->st); i++) {
749         st = a->st + i;
750         if (st->node == NULL)
751             continue;
752         hda_codec_parse_fmt(st->format, &st->as);
753         hda_audio_setup(st);
754         hda_audio_set_amp(st);
755         hda_audio_set_running(st, a->running_real[st->output * 16 + st->stream]);
756     }
757     return 0;
758 }
759
760 static void hda_audio_reset(DeviceState *dev)
761 {
762     HDAAudioState *a = HDA_AUDIO(dev);
763     HDAAudioStream *st;
764     int i;
765
766     dprint(a, 1, "%s\n", __func__);
767     for (i = 0; i < ARRAY_SIZE(a->st); i++) {
768         st = a->st + i;
769         if (st->node != NULL) {
770             hda_audio_set_running(st, false);
771         }
772     }
773 }
774
775 static bool vmstate_hda_audio_stream_buf_needed(void *opaque)
776 {
777     HDAAudioStream *st = opaque;
778     return st->state->use_timer;
779 }
780
781 static const VMStateDescription vmstate_hda_audio_stream_buf = {
782     .name = "hda-audio-stream/buffer",
783     .version_id = 1,
784     .needed = vmstate_hda_audio_stream_buf_needed,
785     .fields = (VMStateField[]) {
786         VMSTATE_BUFFER(buf, HDAAudioStream),
787         VMSTATE_INT64(rpos, HDAAudioStream),
788         VMSTATE_INT64(wpos, HDAAudioStream),
789         VMSTATE_TIMER_PTR(buft, HDAAudioStream),
790         VMSTATE_INT64(buft_start, HDAAudioStream),
791         VMSTATE_END_OF_LIST()
792     }
793 };
794
795 static const VMStateDescription vmstate_hda_audio_stream = {
796     .name = "hda-audio-stream",
797     .version_id = 1,
798     .fields = (VMStateField[]) {
799         VMSTATE_UINT32(stream, HDAAudioStream),
800         VMSTATE_UINT32(channel, HDAAudioStream),
801         VMSTATE_UINT32(format, HDAAudioStream),
802         VMSTATE_UINT32(gain_left, HDAAudioStream),
803         VMSTATE_UINT32(gain_right, HDAAudioStream),
804         VMSTATE_BOOL(mute_left, HDAAudioStream),
805         VMSTATE_BOOL(mute_right, HDAAudioStream),
806         VMSTATE_UINT32(compat_bpos, HDAAudioStream),
807         VMSTATE_BUFFER(compat_buf, HDAAudioStream),
808         VMSTATE_END_OF_LIST()
809     },
810     .subsections = (const VMStateDescription * []) {
811         &vmstate_hda_audio_stream_buf,
812         NULL
813     }
814 };
815
816 static const VMStateDescription vmstate_hda_audio = {
817     .name = "hda-audio",
818     .version_id = 2,
819     .post_load = hda_audio_post_load,
820     .fields = (VMStateField[]) {
821         VMSTATE_STRUCT_ARRAY(st, HDAAudioState, 4, 0,
822                              vmstate_hda_audio_stream,
823                              HDAAudioStream),
824         VMSTATE_BOOL_ARRAY(running_compat, HDAAudioState, 16),
825         VMSTATE_BOOL_ARRAY_V(running_real, HDAAudioState, 2 * 16, 2),
826         VMSTATE_END_OF_LIST()
827     }
828 };
829
830 static Property hda_audio_properties[] = {
831     DEFINE_PROP_UINT32("debug", HDAAudioState, debug,   0),
832     DEFINE_PROP_BOOL("mixer", HDAAudioState, mixer,  true),
833     DEFINE_PROP_BOOL("use-timer", HDAAudioState, use_timer, false),
834     DEFINE_PROP_END_OF_LIST(),
835 };
836
837 static int hda_audio_init_output(HDACodecDevice *hda)
838 {
839     HDAAudioState *a = HDA_AUDIO(hda);
840
841     if (!a->mixer) {
842         return hda_audio_init(hda, &output_nomixemu);
843     } else {
844         return hda_audio_init(hda, &output_mixemu);
845     }
846 }
847
848 static int hda_audio_init_duplex(HDACodecDevice *hda)
849 {
850     HDAAudioState *a = HDA_AUDIO(hda);
851
852     if (!a->mixer) {
853         return hda_audio_init(hda, &duplex_nomixemu);
854     } else {
855         return hda_audio_init(hda, &duplex_mixemu);
856     }
857 }
858
859 static int hda_audio_init_micro(HDACodecDevice *hda)
860 {
861     HDAAudioState *a = HDA_AUDIO(hda);
862
863     if (!a->mixer) {
864         return hda_audio_init(hda, &micro_nomixemu);
865     } else {
866         return hda_audio_init(hda, &micro_mixemu);
867     }
868 }
869
870 static void hda_audio_base_class_init(ObjectClass *klass, void *data)
871 {
872     DeviceClass *dc = DEVICE_CLASS(klass);
873     HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass);
874
875     k->exit = hda_audio_exit;
876     k->command = hda_audio_command;
877     k->stream = hda_audio_stream;
878     set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
879     dc->reset = hda_audio_reset;
880     dc->vmsd = &vmstate_hda_audio;
881     dc->props = hda_audio_properties;
882 }
883
884 static const TypeInfo hda_audio_info = {
885     .name          = TYPE_HDA_AUDIO,
886     .parent        = TYPE_HDA_CODEC_DEVICE,
887     .class_init    = hda_audio_base_class_init,
888     .abstract      = true,
889 };
890
891 static void hda_audio_output_class_init(ObjectClass *klass, void *data)
892 {
893     DeviceClass *dc = DEVICE_CLASS(klass);
894     HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass);
895
896     k->init = hda_audio_init_output;
897     dc->desc = "HDA Audio Codec, output-only (line-out)";
898 }
899
900 static const TypeInfo hda_audio_output_info = {
901     .name          = "hda-output",
902     .parent        = TYPE_HDA_AUDIO,
903     .instance_size = sizeof(HDAAudioState),
904     .class_init    = hda_audio_output_class_init,
905 };
906
907 static void hda_audio_duplex_class_init(ObjectClass *klass, void *data)
908 {
909     DeviceClass *dc = DEVICE_CLASS(klass);
910     HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass);
911
912     k->init = hda_audio_init_duplex;
913     dc->desc = "HDA Audio Codec, duplex (line-out, line-in)";
914 }
915
916 static const TypeInfo hda_audio_duplex_info = {
917     .name          = "hda-duplex",
918     .parent        = TYPE_HDA_AUDIO,
919     .instance_size = sizeof(HDAAudioState),
920     .class_init    = hda_audio_duplex_class_init,
921 };
922
923 static void hda_audio_micro_class_init(ObjectClass *klass, void *data)
924 {
925     DeviceClass *dc = DEVICE_CLASS(klass);
926     HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass);
927
928     k->init = hda_audio_init_micro;
929     dc->desc = "HDA Audio Codec, duplex (speaker, microphone)";
930 }
931
932 static const TypeInfo hda_audio_micro_info = {
933     .name          = "hda-micro",
934     .parent        = TYPE_HDA_AUDIO,
935     .instance_size = sizeof(HDAAudioState),
936     .class_init    = hda_audio_micro_class_init,
937 };
938
939 static void hda_audio_register_types(void)
940 {
941     type_register_static(&hda_audio_info);
942     type_register_static(&hda_audio_output_info);
943     type_register_static(&hda_audio_duplex_info);
944     type_register_static(&hda_audio_micro_info);
945 }
946
947 type_init(hda_audio_register_types)
This page took 0.079359 seconds and 4 git commands to generate.