diff --git a/audio/audio.h b/audio/audio.h index ad2457f4de95bd9961efdc09ae114b05d315e3a3..3257165b05412fbaa637b5ecc70a51702320cf1a 100644 --- a/audio/audio.h +++ b/audio/audio.h @@ -27,6 +27,7 @@ #include "qemu/queue.h" #include "qapi/qapi-types-audio.h" +#include "hw/qdev-properties.h" typedef void (*audio_callback_fn) (void *opaque, int avail); @@ -181,4 +182,7 @@ void audio_legacy_help(void); AudioState *audio_state_by_name(const char *name); const char *audio_get_id(QEMUSoundCard *card); +#define DEFINE_AUDIO_PROPERTIES(_s, _f) \ + DEFINE_PROP_AUDIODEV("audiodev", _s, _f) + #endif /* QEMU_AUDIO_H */ diff --git a/hw/audio/ac97.c b/hw/audio/ac97.c index 115ee51c7ca2d1d8b23b488c555501d90ef6a29e..b4c0b690d720858ad84824a848d6acadd45f8dd9 100644 --- a/hw/audio/ac97.c +++ b/hw/audio/ac97.c @@ -1410,6 +1410,7 @@ static int ac97_init (PCIBus *bus) } static Property ac97_properties[] = { + DEFINE_AUDIO_PROPERTIES(AC97LinkState, card), DEFINE_PROP_UINT32 ("use_broken_id", AC97LinkState, use_broken_id, 0), DEFINE_PROP_END_OF_LIST (), }; diff --git a/hw/audio/adlib.c b/hw/audio/adlib.c index 2f4aacbf43d8a7b3e8631e24c1a92ae88cd0152f..64a1060b807a1f64e83b07c2005feb10d26b5e27 100644 --- a/hw/audio/adlib.c +++ b/hw/audio/adlib.c @@ -299,6 +299,7 @@ static void adlib_realizefn (DeviceState *dev, Error **errp) } static Property adlib_properties[] = { + DEFINE_AUDIO_PROPERTIES(AdlibState, card), DEFINE_PROP_UINT32 ("iobase", AdlibState, port, 0x220), DEFINE_PROP_UINT32 ("freq", AdlibState, freq, 44100), DEFINE_PROP_END_OF_LIST (), diff --git a/hw/audio/cs4231a.c b/hw/audio/cs4231a.c index d77a4e713e3f0471affb293c98f8fe08ee3f0ca8..5b7baeae256d9b9b2350d73abad89422f6b38c7f 100644 --- a/hw/audio/cs4231a.c +++ b/hw/audio/cs4231a.c @@ -690,6 +690,7 @@ static int cs4231a_init (ISABus *bus) } static Property cs4231a_properties[] = { + DEFINE_AUDIO_PROPERTIES(CSState, card), DEFINE_PROP_UINT32 ("iobase", CSState, port, 0x534), DEFINE_PROP_UINT32 ("irq", CSState, irq, 9), DEFINE_PROP_UINT32 ("dma", CSState, dma, 3), diff --git a/hw/audio/es1370.c b/hw/audio/es1370.c index 39deecbbc61b5a7d01e49cebaac9ad696797d34c..88f886491b96b2dcb7d010c41222adf624568ce6 100644 --- a/hw/audio/es1370.c +++ b/hw/audio/es1370.c @@ -887,6 +887,11 @@ static int es1370_init (PCIBus *bus) return 0; } +static Property es1370_properties[] = { + DEFINE_AUDIO_PROPERTIES(ES1370State, card), + DEFINE_PROP_END_OF_LIST(), +}; + static void es1370_class_init (ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS (klass); @@ -903,6 +908,7 @@ static void es1370_class_init (ObjectClass *klass, void *data) dc->desc = "ENSONIQ AudioPCI ES1370"; dc->vmsd = &vmstate_es1370; dc->reset = es1370_on_reset; + dc->props = es1370_properties; } static const TypeInfo es1370_info = { @@ -923,4 +929,3 @@ static void es1370_register_types (void) } type_init (es1370_register_types) - diff --git a/hw/audio/gus.c b/hw/audio/gus.c index dbfe7cf63428ed5732bdd2bbf787c0f24ce4bb2d..effec31d356d603150caa18bf4f59b0ca54d361e 100644 --- a/hw/audio/gus.c +++ b/hw/audio/gus.c @@ -299,6 +299,7 @@ static int GUS_init (ISABus *bus) } static Property gus_properties[] = { + DEFINE_AUDIO_PROPERTIES(GUSState, card), DEFINE_PROP_UINT32 ("freq", GUSState, freq, 44100), DEFINE_PROP_UINT32 ("iobase", GUSState, port, 0x240), DEFINE_PROP_UINT32 ("irq", GUSState, emu.gusirq, 7), diff --git a/hw/audio/hda-codec.c b/hw/audio/hda-codec.c index 4fee0673d9ca193b9bc216ccb2f22b95cd2cdf9e..68fe1de987c216ddcaa257adfb7a1be06ee501da 100644 --- a/hw/audio/hda-codec.c +++ b/hw/audio/hda-codec.c @@ -841,6 +841,7 @@ static const VMStateDescription vmstate_hda_audio = { }; static Property hda_audio_properties[] = { + DEFINE_AUDIO_PROPERTIES(HDAAudioState, card), DEFINE_PROP_UINT32("debug", HDAAudioState, debug, 0), DEFINE_PROP_BOOL("mixer", HDAAudioState, mixer, true), DEFINE_PROP_BOOL("use-timer", HDAAudioState, use_timer, true), diff --git a/hw/audio/milkymist-ac97.c b/hw/audio/milkymist-ac97.c index 481dde10a1937aa1764720084a749dd9bb8cf446..853b4ed8746b5ce19e2ed4c1379aa2b8e8ec3496 100644 --- a/hw/audio/milkymist-ac97.c +++ b/hw/audio/milkymist-ac97.c @@ -330,6 +330,11 @@ static const VMStateDescription vmstate_milkymist_ac97 = { } }; +static Property milkymist_ac97_properties[] = { + DEFINE_AUDIO_PROPERTIES(MilkymistAC97State, card), + DEFINE_PROP_END_OF_LIST(), +}; + static void milkymist_ac97_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -337,6 +342,7 @@ static void milkymist_ac97_class_init(ObjectClass *klass, void *data) dc->realize = milkymist_ac97_realize; dc->reset = milkymist_ac97_reset; dc->vmsd = &vmstate_milkymist_ac97; + dc->props = milkymist_ac97_properties; } static const TypeInfo milkymist_ac97_info = { diff --git a/hw/audio/pcspk.c b/hw/audio/pcspk.c index 016946d4b280be56f74f7d57c2c74f5437d95850..307c6647254a266ac3e1b80dd99a8d485c85da44 100644 --- a/hw/audio/pcspk.c +++ b/hw/audio/pcspk.c @@ -209,6 +209,7 @@ static const VMStateDescription vmstate_spk = { }; static Property pcspk_properties[] = { + DEFINE_AUDIO_PROPERTIES(PCSpkState, card), DEFINE_PROP_UINT32("iobase", PCSpkState, iobase, -1), DEFINE_PROP_BOOL("migrate", PCSpkState, migrate, true), DEFINE_PROP_END_OF_LIST(), diff --git a/hw/audio/pl041.c b/hw/audio/pl041.c index ca9139907880cec2d38191b64bace69858942c80..c30417d46d51ee16ad28c08c6a95a4dc8ddcb2a9 100644 --- a/hw/audio/pl041.c +++ b/hw/audio/pl041.c @@ -625,6 +625,7 @@ static const VMStateDescription vmstate_pl041 = { }; static Property pl041_device_properties[] = { + DEFINE_AUDIO_PROPERTIES(PL041State, codec.card), /* Non-compact FIFO depth property */ DEFINE_PROP_UINT32("nc_fifo_depth", PL041State, fifo_depth, DEFAULT_FIFO_DEPTH), diff --git a/hw/audio/sb16.c b/hw/audio/sb16.c index 3ad01f3599b4c0c832db9909aac65c55e67d6666..7e50ab8a84a3cf457af2c7d248f138d5d6ac1139 100644 --- a/hw/audio/sb16.c +++ b/hw/audio/sb16.c @@ -1422,6 +1422,7 @@ static int SB16_init (ISABus *bus) } static Property sb16_properties[] = { + DEFINE_AUDIO_PROPERTIES(SB16State, card), DEFINE_PROP_UINT32 ("version", SB16State, ver, 0x0405), /* 4.5 */ DEFINE_PROP_UINT32 ("iobase", SB16State, port, 0x220), DEFINE_PROP_UINT32 ("irq", SB16State, irq, 5), diff --git a/hw/audio/wm8750.c b/hw/audio/wm8750.c index 9f6df5d59c9b933201018fec86353d29fe8dd4a6..a8725abf6a3744d1e06310d9dbfed89e053dc2f2 100644 --- a/hw/audio/wm8750.c +++ b/hw/audio/wm8750.c @@ -702,6 +702,11 @@ void wm8750_set_bclk_in(void *opaque, int new_hz) wm8750_clk_update(s, 1); } +static Property wm8750_properties[] = { + DEFINE_AUDIO_PROPERTIES(WM8750State, card), + DEFINE_PROP_END_OF_LIST(), +}; + static void wm8750_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -712,6 +717,7 @@ static void wm8750_class_init(ObjectClass *klass, void *data) sc->recv = wm8750_rx; sc->send = wm8750_tx; dc->vmsd = &vmstate_wm8750; + dc->props = wm8750_properties; } static const TypeInfo wm8750_info = { diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c index fceab9afd5ea0422d987b051bbb1977acc06026e..70bfd4809b1713db25eb7491d7dff13c63a5fe03 100644 --- a/hw/core/qdev-properties-system.c +++ b/hw/core/qdev-properties-system.c @@ -11,6 +11,7 @@ */ #include "qemu/osdep.h" +#include "audio/audio.h" #include "net/net.h" #include "hw/qdev-properties.h" #include "qapi/error.h" @@ -353,6 +354,62 @@ const PropertyInfo qdev_prop_netdev = { }; +/* --- audiodev --- */ +static void get_audiodev(Object *obj, Visitor *v, const char* name, + void *opaque, Error **errp) +{ + DeviceState *dev = DEVICE(obj); + Property *prop = opaque; + QEMUSoundCard *card = qdev_get_prop_ptr(dev, prop); + char *p = g_strdup(audio_get_id(card)); + + visit_type_str(v, name, &p, errp); + g_free(p); +} + +static void set_audiodev(Object *obj, Visitor *v, const char* name, + void *opaque, Error **errp) +{ + DeviceState *dev = DEVICE(obj); + Property *prop = opaque; + QEMUSoundCard *card = qdev_get_prop_ptr(dev, prop); + AudioState *state; + Error *local_err = NULL; + int err = 0; + char *str; + + if (dev->realized) { + qdev_prop_set_after_realize(dev, name, errp); + return; + } + + visit_type_str(v, name, &str, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + state = audio_state_by_name(str); + + if (!state) { + err = -ENOENT; + goto out; + } + card->state = state; + +out: + error_set_from_qdev_prop_error(errp, err, dev, prop, str); + g_free(str); +} + +const PropertyInfo qdev_prop_audiodev = { + .name = "str", + .description = "ID of an audiodev to use as a backend", + /* release done on shutdown */ + .get = get_audiodev, + .set = set_audiodev, +}; + void qdev_prop_set_drive(DeviceState *dev, const char *name, BlockBackend *value, Error **errp) { diff --git a/hw/usb/dev-audio.c b/hw/usb/dev-audio.c index d3ca3bd1ab9e3635aeabb8efeae8ece7f9ee3cb2..ae42e5a2f1d08339ddbe3cc0eb1068b87d0b718f 100644 --- a/hw/usb/dev-audio.c +++ b/hw/usb/dev-audio.c @@ -667,6 +667,7 @@ static const VMStateDescription vmstate_usb_audio = { }; static Property usb_audio_properties[] = { + DEFINE_AUDIO_PROPERTIES(USBAudioState, card), DEFINE_PROP_UINT32("debug", USBAudioState, debug, 0), DEFINE_PROP_UINT32("buffer", USBAudioState, buffer, 32 * USBAUDIO_PACKET_SIZE), diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h index bb34a614e2cc719c1a502d0b7be59f3d59f36814..2e98dd60db85eae32442375f0f193a09beb64d79 100644 --- a/include/hw/qdev-properties.h +++ b/include/hw/qdev-properties.h @@ -33,6 +33,7 @@ extern const PropertyInfo qdev_prop_blocksize; extern const PropertyInfo qdev_prop_pci_host_devaddr; extern const PropertyInfo qdev_prop_uuid; extern const PropertyInfo qdev_prop_arraylen; +extern const PropertyInfo qdev_prop_audiodev; extern const PropertyInfo qdev_prop_link; extern const PropertyInfo qdev_prop_off_auto_pcibar; extern const PropertyInfo qdev_prop_pcie_link_speed; @@ -234,6 +235,8 @@ extern const PropertyInfo qdev_prop_pcie_link_width; + type_check(QemuUUID, typeof_field(_state, _field)), \ .set_default = true, \ } +#define DEFINE_PROP_AUDIODEV(_n, _s, _f) \ + DEFINE_PROP(_n, _s, _f, qdev_prop_audiodev, QEMUSoundCard) #define DEFINE_PROP_END_OF_LIST() \ {}