--- hw/hda-audio.c | 58 ++++++++++++++++++++++++++++++++++--------------------- hw/intel-hda.c | 43 +++++++++++++++++++++++++++-------------- hw/intel-hda.h | 26 ++++++++++++++++-------- 3 files changed, 81 insertions(+), 46 deletions(-)
diff --git a/hw/hda-audio.c b/hw/hda-audio.c index ffdd799..71831a3 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 09459b8..97a6216 100644 --- a/hw/intel-hda.c +++ b/hw/intel-hda.c @@ -50,10 +50,9 @@ void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus, 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); + HDACodecDevice *dev = HDA_CODEC_DEVICE(qdev); + HDACodecDeviceClass *hcc = 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 hcc->init(dev); } static int hda_codec_dev_exit(DeviceState *qdev) { - HDACodecDevice *dev = DO_UPCAST(HDACodecDevice, qdev, qdev); + HDACodecDevice *dev = HDA_CODEC_DEVICE(qdev); + HDACodecDeviceClass *hcc = HDA_CODEC_DEVICE_GET_CLASS(dev); - if (dev->info->exit) { - dev->info->exit(dev); + if (hcc->exit) { + hcc->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_subclass(info, TYPE_HDA_CODEC_DEVICE); } 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 *hcc; 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); + hcc = HDA_CODEC_DEVICE_GET_CLASS(codec); + hcc->command(codec, nid, data); return 0; } @@ -491,9 +493,11 @@ static void intel_hda_notify_codecs(IntelHDAState *d, uint32_t stream, bool runn HDACodecDevice *cdev; QTAILQ_FOREACH(qdev, &d->codecs.qbus.children, sibling) { + HDACodecDeviceClass *hcc; cdev = DO_UPCAST(HDACodecDevice, qdev, qdev); - if (cdev->info->stream) { - cdev->info->stream(cdev, stream, running, output); + hcc = HDA_CODEC_DEVICE_GET_CLASS(cdev); + if (hcc->stream) { + hcc->stream(cdev, stream, running, output); } } } @@ -1262,9 +1266,18 @@ static PCIDeviceInfo intel_hda_info = { } }; +static TypeInfo hda_codec_device_type_info = { + .name = TYPE_HDA_CODEC_DEVICE, + .parent = TYPE_DEVICE, + .instance_size = sizeof(HDACodecDevice), + .abstract = true, + .class_size = sizeof(HDACodecDeviceClass), +}; + static void intel_hda_register(void) { pci_qdev_register(&intel_hda_info); + type_register_static(&hda_codec_device_type_info); } device_init(intel_hda_register); diff --git a/hw/intel-hda.h b/hw/intel-hda.h index 65fd2a8..f523587 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); -- 1.7.4.1