]> git.proxmox.com Git - mirror_qemu.git/blame - hw/audio/soundhw.c
Merge tag 'pull-maintainer-may24-160524-2' of https://gitlab.com/stsquad/qemu into...
[mirror_qemu.git] / hw / audio / soundhw.c
CommitLineData
ca89f720
EH
1/*
2 * QEMU System Emulator
3 *
4 * Copyright (c) 2003-2008 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24#include "qemu/osdep.h"
542e0c55 25#include "qemu/option.h"
ca89f720
EH
26#include "qemu/help_option.h"
27#include "qemu/error-report.h"
9c50b8aa 28#include "qapi/error.h"
ca89f720 29#include "qom/object.h"
039a6837 30#include "hw/qdev-properties.h"
ca89f720
EH
31#include "hw/isa/isa.h"
32#include "hw/pci/pci.h"
8a824e4d 33#include "hw/audio/soundhw.h"
ca89f720
EH
34
35struct soundhw {
36 const char *name;
37 const char *descr;
542e0c55 38 const char *typename;
ca89f720 39 int isa;
039a6837 40 int (*init_pci) (PCIBus *bus, const char *audiodev);
ca89f720
EH
41};
42
43static struct soundhw soundhw[9];
44static int soundhw_count;
45
ca89f720 46void pci_register_soundhw(const char *name, const char *descr,
039a6837 47 int (*init_pci)(PCIBus *bus, const char *audiodev))
ca89f720
EH
48{
49 assert(soundhw_count < ARRAY_SIZE(soundhw) - 1);
50 soundhw[soundhw_count].name = name;
51 soundhw[soundhw_count].descr = descr;
52 soundhw[soundhw_count].isa = 0;
6033b9ec 53 soundhw[soundhw_count].init_pci = init_pci;
ca89f720
EH
54 soundhw_count++;
55}
56
542e0c55
GH
57void deprecated_register_soundhw(const char *name, const char *descr,
58 int isa, const char *typename)
59{
60 assert(soundhw_count < ARRAY_SIZE(soundhw) - 1);
61 soundhw[soundhw_count].name = name;
62 soundhw[soundhw_count].descr = descr;
63 soundhw[soundhw_count].isa = isa;
64 soundhw[soundhw_count].typename = typename;
65 soundhw_count++;
66}
67
eef5fdf3
PB
68void show_valid_soundhw(void)
69{
70 struct soundhw *c;
71
72 if (soundhw_count) {
73 printf("Valid sound card names (comma separated):\n");
74 for (c = soundhw; c->name; ++c) {
75 printf ("%-11s %s\n", c->name, c->descr);
76 }
77 } else {
78 printf("Machine has no user-selectable audio hardware "
79 "(it may or may not have always-present audio hardware).\n");
80 }
81}
82
9c50b8aa 83static struct soundhw *selected = NULL;
039a6837 84static const char *audiodev_id;
9c50b8aa 85
badf708d 86void select_soundhw(const char *name, const char *audiodev)
ca89f720
EH
87{
88 struct soundhw *c;
89
9c50b8aa
PB
90 if (selected) {
91 error_setg(&error_fatal, "only one -soundhw option is allowed");
92 }
93
67aaa96a 94 for (c = soundhw; c->name; ++c) {
badf708d 95 if (g_str_equal(c->name, name)) {
67aaa96a 96 selected = c;
039a6837 97 audiodev_id = audiodev;
67aaa96a 98 break;
ca89f720 99 }
67aaa96a 100 }
ca89f720 101
67aaa96a 102 if (!c->name) {
badf708d 103 error_report("Unknown sound card name `%s'", name);
67aaa96a
PB
104 show_valid_soundhw();
105 exit(1);
ca89f720
EH
106 }
107}
108
4c565674 109void soundhw_init(void)
ca89f720 110{
9c50b8aa 111 struct soundhw *c = selected;
ca89f720
EH
112 ISABus *isa_bus = (ISABus *) object_resolve_path_type("", TYPE_ISA_BUS, NULL);
113 PCIBus *pci_bus = (PCIBus *) object_resolve_path_type("", TYPE_PCI_BUS, NULL);
bf521c56 114 BusState *bus;
ca89f720 115
9c50b8aa
PB
116 if (!c) {
117 return;
118 }
bf521c56
PB
119 if (c->isa) {
120 if (!isa_bus) {
121 error_report("ISA bus not available for %s", c->name);
122 exit(1);
9c50b8aa 123 }
bf521c56 124 bus = BUS(isa_bus);
9c50b8aa 125 } else {
9c50b8aa
PB
126 if (!pci_bus) {
127 error_report("PCI bus not available for %s", c->name);
128 exit(1);
ca89f720 129 }
bf521c56
PB
130 bus = BUS(pci_bus);
131 }
132
133 if (c->typename) {
134 DeviceState *dev = qdev_new(c->typename);
039a6837 135 qdev_prop_set_string(dev, "audiodev", audiodev_id);
bf521c56
PB
136 qdev_realize_and_unref(dev, bus, &error_fatal);
137 } else {
138 assert(!c->isa);
039a6837 139 c->init_pci(pci_bus, audiodev_id);
ca89f720
EH
140 }
141}
142