Revision ba43d289
b/hw/hda-audio.c | ||
---|---|---|
466 | 466 |
QEMUSoundCard card; |
467 | 467 |
const desc_codec *desc; |
468 | 468 |
HDAAudioStream st[4]; |
469 |
bool running[16]; |
|
469 |
bool running_compat[16]; |
|
470 |
bool running_real[2 * 16]; |
|
470 | 471 |
|
471 | 472 |
/* properties */ |
472 | 473 |
uint32_t debug; |
... | ... | |
663 | 664 |
st->channel = payload & 0x0f; |
664 | 665 |
dprint(a, 2, "%s: stream %d, channel %d\n", |
665 | 666 |
st->node->name, st->stream, st->channel); |
666 |
hda_audio_set_running(st, a->running[st->stream]);
|
|
667 |
hda_audio_set_running(st, a->running_real[st->output * 16 + st->stream]);
|
|
667 | 668 |
hda_codec_response(hda, true, 0); |
668 | 669 |
break; |
669 | 670 |
case AC_VERB_GET_CONV: |
... | ... | |
746 | 747 |
hda_codec_response(hda, true, 0); |
747 | 748 |
} |
748 | 749 |
|
749 |
static void hda_audio_stream(HDACodecDevice *hda, uint32_t stnr, bool running) |
|
750 |
static void hda_audio_stream(HDACodecDevice *hda, uint32_t stnr, bool running, bool output)
|
|
750 | 751 |
{ |
751 | 752 |
HDAAudioState *a = DO_UPCAST(HDAAudioState, hda, hda); |
752 | 753 |
int s; |
753 | 754 |
|
754 |
a->running[stnr] = running; |
|
755 |
a->running_compat[stnr] = running; |
|
756 |
a->running_real[output * 16 + stnr] = running; |
|
755 | 757 |
for (s = 0; s < ARRAY_SIZE(a->st); s++) { |
756 | 758 |
if (a->st[s].node == NULL) { |
757 | 759 |
continue; |
758 | 760 |
} |
761 |
if (a->st[s].output != output) { |
|
762 |
continue; |
|
763 |
} |
|
759 | 764 |
if (a->st[s].stream != stnr) { |
760 | 765 |
continue; |
761 | 766 |
} |
... | ... | |
837 | 842 |
int i; |
838 | 843 |
|
839 | 844 |
dprint(a, 1, "%s\n", __FUNCTION__); |
845 |
if (version == 1) { |
|
846 |
/* assume running_compat[] is for output streams */ |
|
847 |
for (i = 0; i < ARRAY_SIZE(a->running_compat); i++) |
|
848 |
a->running_real[16 + i] = a->running_compat[i]; |
|
849 |
} |
|
850 |
|
|
840 | 851 |
for (i = 0; i < ARRAY_SIZE(a->st); i++) { |
841 | 852 |
st = a->st + i; |
842 | 853 |
if (st->node == NULL) |
... | ... | |
844 | 855 |
hda_codec_parse_fmt(st->format, &st->as); |
845 | 856 |
hda_audio_setup(st); |
846 | 857 |
hda_audio_set_amp(st); |
847 |
hda_audio_set_running(st, a->running[st->stream]);
|
|
858 |
hda_audio_set_running(st, a->running_real[st->output * 16 + st->stream]);
|
|
848 | 859 |
} |
849 | 860 |
return 0; |
850 | 861 |
} |
... | ... | |
868 | 879 |
|
869 | 880 |
static const VMStateDescription vmstate_hda_audio = { |
870 | 881 |
.name = "hda-audio", |
871 |
.version_id = 1,
|
|
882 |
.version_id = 2,
|
|
872 | 883 |
.post_load = hda_audio_post_load, |
873 | 884 |
.fields = (VMStateField []) { |
874 | 885 |
VMSTATE_STRUCT_ARRAY(st, HDAAudioState, 4, 0, |
875 | 886 |
vmstate_hda_audio_stream, |
876 | 887 |
HDAAudioStream), |
877 |
VMSTATE_BOOL_ARRAY(running, HDAAudioState, 16), |
|
888 |
VMSTATE_BOOL_ARRAY(running_compat, HDAAudioState, 16), |
|
889 |
VMSTATE_BOOL_ARRAY_V(running_real, HDAAudioState, 2 * 16, 2), |
|
878 | 890 |
VMSTATE_END_OF_LIST() |
879 | 891 |
} |
880 | 892 |
}; |
b/hw/intel-hda.c | ||
---|---|---|
485 | 485 |
st->bp = 0; |
486 | 486 |
} |
487 | 487 |
|
488 |
static void intel_hda_notify_codecs(IntelHDAState *d, uint32_t stream, bool running) |
|
488 |
static void intel_hda_notify_codecs(IntelHDAState *d, uint32_t stream, bool running, bool output)
|
|
489 | 489 |
{ |
490 | 490 |
DeviceState *qdev; |
491 | 491 |
HDACodecDevice *cdev; |
... | ... | |
493 | 493 |
QLIST_FOREACH(qdev, &d->codecs.qbus.children, sibling) { |
494 | 494 |
cdev = DO_UPCAST(HDACodecDevice, qdev, qdev); |
495 | 495 |
if (cdev->info->stream) { |
496 |
cdev->info->stream(cdev, stream, running); |
|
496 |
cdev->info->stream(cdev, stream, running, output);
|
|
497 | 497 |
} |
498 | 498 |
} |
499 | 499 |
} |
... | ... | |
567 | 567 |
|
568 | 568 |
static void intel_hda_set_st_ctl(IntelHDAState *d, const IntelHDAReg *reg, uint32_t old) |
569 | 569 |
{ |
570 |
bool output = reg->stream >= 4; |
|
570 | 571 |
IntelHDAStream *st = d->st + reg->stream; |
571 | 572 |
|
572 | 573 |
if (st->ctl & 0x01) { |
... | ... | |
582 | 583 |
dprint(d, 1, "st #%d: start %d (ring buf %d bytes)\n", |
583 | 584 |
reg->stream, stnr, st->cbl); |
584 | 585 |
intel_hda_parse_bdl(d, st); |
585 |
intel_hda_notify_codecs(d, stnr, true); |
|
586 |
intel_hda_notify_codecs(d, stnr, true, output);
|
|
586 | 587 |
} else { |
587 | 588 |
/* stop */ |
588 | 589 |
dprint(d, 1, "st #%d: stop %d\n", reg->stream, stnr); |
589 |
intel_hda_notify_codecs(d, stnr, false); |
|
590 |
intel_hda_notify_codecs(d, stnr, false, output);
|
|
590 | 591 |
} |
591 | 592 |
} |
592 | 593 |
intel_hda_update_irq(d); |
b/hw/intel-hda.h | ||
---|---|---|
34 | 34 |
int (*init)(HDACodecDevice *dev); |
35 | 35 |
int (*exit)(HDACodecDevice *dev); |
36 | 36 |
void (*command)(HDACodecDevice *dev, uint32_t nid, uint32_t data); |
37 |
void (*stream)(HDACodecDevice *dev, uint32_t stnr, bool running); |
|
37 |
void (*stream)(HDACodecDevice *dev, uint32_t stnr, bool running, bool output);
|
|
38 | 38 |
}; |
39 | 39 |
|
40 | 40 |
void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus, |
Also available in: Unified diff