diff --git a/hw/hda-audio.c b/hw/hda-audio.c index 8053c74d9c..2b3ce2f504 100644 --- a/hw/hda-audio.c +++ b/hw/hda-audio.c @@ -906,33 +906,47 @@ static int hda_audio_init_duplex(HDACodecDevice *hda) return hda_audio_init(hda, &duplex); } -static HDACodecDeviceInfo hda_audio_info_output = { - .qdev.name = "hda-output", - .qdev.desc = "HDA Audio Codec, output-only", - .qdev.size = sizeof(HDAAudioState), - .qdev.vmsd = &vmstate_hda_audio, - .qdev.props = hda_audio_properties, - .init = hda_audio_init_output, - .exit = hda_audio_exit, - .command = hda_audio_command, - .stream = hda_audio_stream, +static void hda_audio_output_class_init(ObjectClass *klass, void *data) +{ + HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass); + + k->init = hda_audio_init_output; + k->exit = hda_audio_exit; + k->command = hda_audio_command; + k->stream = hda_audio_stream; +} + +static DeviceInfo hda_audio_output_info = { + .name = "hda-output", + .desc = "HDA Audio Codec, output-only", + .size = sizeof(HDAAudioState), + .vmsd = &vmstate_hda_audio, + .props = hda_audio_properties, + .class_init = hda_audio_output_class_init, }; -static HDACodecDeviceInfo hda_audio_info_duplex = { - .qdev.name = "hda-duplex", - .qdev.desc = "HDA Audio Codec, duplex", - .qdev.size = sizeof(HDAAudioState), - .qdev.vmsd = &vmstate_hda_audio, - .qdev.props = hda_audio_properties, - .init = hda_audio_init_duplex, - .exit = hda_audio_exit, - .command = hda_audio_command, - .stream = hda_audio_stream, +static void hda_audio_duplex_class_init(ObjectClass *klass, void *data) +{ + HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass); + + k->init = hda_audio_init_duplex; + k->exit = hda_audio_exit; + k->command = hda_audio_command; + k->stream = hda_audio_stream; +} + +static DeviceInfo hda_audio_duplex_info = { + .name = "hda-duplex", + .desc = "HDA Audio Codec, duplex", + .size = sizeof(HDAAudioState), + .vmsd = &vmstate_hda_audio, + .props = hda_audio_properties, + .class_init = hda_audio_duplex_class_init, }; static void hda_audio_register(void) { - hda_codec_register(&hda_audio_info_output); - hda_codec_register(&hda_audio_info_duplex); + hda_codec_register(&hda_audio_output_info); + hda_codec_register(&hda_audio_duplex_info); } device_init(hda_audio_register); diff --git a/hw/intel-hda.c b/hw/intel-hda.c index 6e1c5de646..f727c22d99 100644 --- a/hw/intel-hda.c +++ b/hw/intel-hda.c @@ -51,9 +51,8 @@ static int hda_codec_dev_init(DeviceState *qdev, DeviceInfo *base) { HDACodecBus *bus = DO_UPCAST(HDACodecBus, qbus, qdev->parent_bus); HDACodecDevice *dev = DO_UPCAST(HDACodecDevice, qdev, qdev); - HDACodecDeviceInfo *info = DO_UPCAST(HDACodecDeviceInfo, qdev, base); + HDACodecDeviceClass *cdc = HDA_CODEC_DEVICE_GET_CLASS(dev); - dev->info = info; if (dev->cad == -1) { dev->cad = bus->next_cad; } @@ -61,25 +60,26 @@ static int hda_codec_dev_init(DeviceState *qdev, DeviceInfo *base) return -1; } bus->next_cad = dev->cad + 1; - return info->init(dev); + return cdc->init(dev); } static int hda_codec_dev_exit(DeviceState *qdev) { HDACodecDevice *dev = DO_UPCAST(HDACodecDevice, qdev, qdev); + HDACodecDeviceClass *cdc = HDA_CODEC_DEVICE_GET_CLASS(dev); - if (dev->info->exit) { - dev->info->exit(dev); + if (cdc->exit) { + cdc->exit(dev); } return 0; } -void hda_codec_register(HDACodecDeviceInfo *info) +void hda_codec_register(DeviceInfo *info) { - info->qdev.init = hda_codec_dev_init; - info->qdev.exit = hda_codec_dev_exit; - info->qdev.bus_info = &hda_codec_bus_info; - qdev_register(&info->qdev); + info->init = hda_codec_dev_init; + info->exit = hda_codec_dev_exit; + info->bus_info = &hda_codec_bus_info; + qdev_register(info); } HDACodecDevice *hda_codec_find(HDACodecBus *bus, uint32_t cad) @@ -283,6 +283,7 @@ static int intel_hda_send_command(IntelHDAState *d, uint32_t verb) { uint32_t cad, nid, data; HDACodecDevice *codec; + HDACodecDeviceClass *cdc; cad = (verb >> 28) & 0x0f; if (verb & (1 << 27)) { @@ -298,7 +299,8 @@ static int intel_hda_send_command(IntelHDAState *d, uint32_t verb) dprint(d, 1, "%s: addressed non-existing codec\n", __FUNCTION__); return -1; } - codec->info->command(codec, nid, data); + cdc = HDA_CODEC_DEVICE_GET_CLASS(codec); + cdc->command(codec, nid, data); return 0; } @@ -491,9 +493,12 @@ static void intel_hda_notify_codecs(IntelHDAState *d, uint32_t stream, bool runn HDACodecDevice *cdev; QTAILQ_FOREACH(qdev, &d->codecs.qbus.children, sibling) { + HDACodecDeviceClass *cdc; + cdev = DO_UPCAST(HDACodecDevice, qdev, qdev); - if (cdev->info->stream) { - cdev->info->stream(cdev, stream, running, output); + cdc = HDA_CODEC_DEVICE_GET_CLASS(cdev); + if (cdc->stream) { + cdc->stream(cdev, stream, running, output); } } } diff --git a/hw/intel-hda.h b/hw/intel-hda.h index 65fd2a85bb..f52358709b 100644 --- a/hw/intel-hda.h +++ b/hw/intel-hda.h @@ -6,9 +6,16 @@ /* --------------------------------------------------------------------- */ /* hda bus */ +#define TYPE_HDA_CODEC_DEVICE "hda-codec" +#define HDA_CODEC_DEVICE(obj) \ + OBJECT_CHECK(HDACodecDevice, (obj), TYPE_HDA_CODEC_DEVICE) +#define HDA_CODEC_DEVICE_CLASS(klass) \ + OBJECT_CLASS_CHECK(HDACodecDeviceClass, (klass), TYPE_HDA_CODEC_DEVICE) +#define HDA_CODEC_DEVICE_GET_CLASS(obj) \ + OBJECT_GET_CLASS(HDACodecDeviceClass, (obj), TYPE_HDA_CODEC_DEVICE) + typedef struct HDACodecBus HDACodecBus; typedef struct HDACodecDevice HDACodecDevice; -typedef struct HDACodecDeviceInfo HDACodecDeviceInfo; typedef void (*hda_codec_response_func)(HDACodecDevice *dev, bool solicited, uint32_t response); @@ -23,24 +30,25 @@ struct HDACodecBus { hda_codec_xfer_func xfer; }; -struct HDACodecDevice { - DeviceState qdev; - HDACodecDeviceInfo *info; - uint32_t cad; /* codec address */ -}; +typedef struct HDACodecDeviceClass +{ + DeviceClass parent_class; -struct HDACodecDeviceInfo { - DeviceInfo qdev; int (*init)(HDACodecDevice *dev); int (*exit)(HDACodecDevice *dev); void (*command)(HDACodecDevice *dev, uint32_t nid, uint32_t data); void (*stream)(HDACodecDevice *dev, uint32_t stnr, bool running, bool output); +} HDACodecDeviceClass; + +struct HDACodecDevice { + DeviceState qdev; + uint32_t cad; /* codec address */ }; void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus, hda_codec_response_func response, hda_codec_xfer_func xfer); -void hda_codec_register(HDACodecDeviceInfo *info); +void hda_codec_register(DeviceInfo *info); HDACodecDevice *hda_codec_find(HDACodecBus *bus, uint32_t cad); void hda_codec_response(HDACodecDevice *dev, bool solicited, uint32_t response);