1ca89f720SEduardo Habkost /*
2ca89f720SEduardo Habkost * QEMU System Emulator
3ca89f720SEduardo Habkost *
4ca89f720SEduardo Habkost * Copyright (c) 2003-2008 Fabrice Bellard
5ca89f720SEduardo Habkost *
6ca89f720SEduardo Habkost * Permission is hereby granted, free of charge, to any person obtaining a copy
7ca89f720SEduardo Habkost * of this software and associated documentation files (the "Software"), to deal
8ca89f720SEduardo Habkost * in the Software without restriction, including without limitation the rights
9ca89f720SEduardo Habkost * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10ca89f720SEduardo Habkost * copies of the Software, and to permit persons to whom the Software is
11ca89f720SEduardo Habkost * furnished to do so, subject to the following conditions:
12ca89f720SEduardo Habkost *
13ca89f720SEduardo Habkost * The above copyright notice and this permission notice shall be included in
14ca89f720SEduardo Habkost * all copies or substantial portions of the Software.
15ca89f720SEduardo Habkost *
16ca89f720SEduardo Habkost * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17ca89f720SEduardo Habkost * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18ca89f720SEduardo Habkost * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19ca89f720SEduardo Habkost * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20ca89f720SEduardo Habkost * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21ca89f720SEduardo Habkost * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22ca89f720SEduardo Habkost * THE SOFTWARE.
23ca89f720SEduardo Habkost */
24ca89f720SEduardo Habkost #include "qemu/osdep.h"
25542e0c55SGerd Hoffmann #include "qemu/option.h"
26ca89f720SEduardo Habkost #include "qemu/help_option.h"
27ca89f720SEduardo Habkost #include "qemu/error-report.h"
289c50b8aaSPaolo Bonzini #include "qapi/error.h"
29ca89f720SEduardo Habkost #include "qom/object.h"
30039a6837SPaolo Bonzini #include "hw/qdev-properties.h"
31ca89f720SEduardo Habkost #include "hw/isa/isa.h"
32ca89f720SEduardo Habkost #include "hw/pci/pci.h"
338a824e4dSEduardo Habkost #include "hw/audio/soundhw.h"
34ca89f720SEduardo Habkost
35ca89f720SEduardo Habkost struct soundhw {
36ca89f720SEduardo Habkost const char *name;
37ca89f720SEduardo Habkost const char *descr;
38542e0c55SGerd Hoffmann const char *typename;
39ca89f720SEduardo Habkost int isa;
40039a6837SPaolo Bonzini int (*init_pci) (PCIBus *bus, const char *audiodev);
41ca89f720SEduardo Habkost };
42ca89f720SEduardo Habkost
43ca89f720SEduardo Habkost static struct soundhw soundhw[9];
44ca89f720SEduardo Habkost static int soundhw_count;
45ca89f720SEduardo Habkost
pci_register_soundhw(const char * name,const char * descr,int (* init_pci)(PCIBus * bus,const char * audiodev))46ca89f720SEduardo Habkost void pci_register_soundhw(const char *name, const char *descr,
47039a6837SPaolo Bonzini int (*init_pci)(PCIBus *bus, const char *audiodev))
48ca89f720SEduardo Habkost {
49ca89f720SEduardo Habkost assert(soundhw_count < ARRAY_SIZE(soundhw) - 1);
50ca89f720SEduardo Habkost soundhw[soundhw_count].name = name;
51ca89f720SEduardo Habkost soundhw[soundhw_count].descr = descr;
52ca89f720SEduardo Habkost soundhw[soundhw_count].isa = 0;
536033b9ecSPaolo Bonzini soundhw[soundhw_count].init_pci = init_pci;
54ca89f720SEduardo Habkost soundhw_count++;
55ca89f720SEduardo Habkost }
56ca89f720SEduardo Habkost
deprecated_register_soundhw(const char * name,const char * descr,int isa,const char * typename)57542e0c55SGerd Hoffmann void deprecated_register_soundhw(const char *name, const char *descr,
58542e0c55SGerd Hoffmann int isa, const char *typename)
59542e0c55SGerd Hoffmann {
60542e0c55SGerd Hoffmann assert(soundhw_count < ARRAY_SIZE(soundhw) - 1);
61542e0c55SGerd Hoffmann soundhw[soundhw_count].name = name;
62542e0c55SGerd Hoffmann soundhw[soundhw_count].descr = descr;
63542e0c55SGerd Hoffmann soundhw[soundhw_count].isa = isa;
64542e0c55SGerd Hoffmann soundhw[soundhw_count].typename = typename;
65542e0c55SGerd Hoffmann soundhw_count++;
66542e0c55SGerd Hoffmann }
67542e0c55SGerd Hoffmann
show_valid_soundhw(void)68eef5fdf3SPaolo Bonzini void show_valid_soundhw(void)
69eef5fdf3SPaolo Bonzini {
70eef5fdf3SPaolo Bonzini struct soundhw *c;
71eef5fdf3SPaolo Bonzini
72eef5fdf3SPaolo Bonzini if (soundhw_count) {
73eef5fdf3SPaolo Bonzini printf("Valid sound card names (comma separated):\n");
74eef5fdf3SPaolo Bonzini for (c = soundhw; c->name; ++c) {
75eef5fdf3SPaolo Bonzini printf ("%-11s %s\n", c->name, c->descr);
76eef5fdf3SPaolo Bonzini }
77eef5fdf3SPaolo Bonzini } else {
78eef5fdf3SPaolo Bonzini printf("Machine has no user-selectable audio hardware "
79eef5fdf3SPaolo Bonzini "(it may or may not have always-present audio hardware).\n");
80eef5fdf3SPaolo Bonzini }
81eef5fdf3SPaolo Bonzini }
82eef5fdf3SPaolo Bonzini
839c50b8aaSPaolo Bonzini static struct soundhw *selected = NULL;
84039a6837SPaolo Bonzini static const char *audiodev_id;
859c50b8aaSPaolo Bonzini
select_soundhw(const char * name,const char * audiodev)86badf708dSPhilippe Mathieu-Daudé void select_soundhw(const char *name, const char *audiodev)
87ca89f720SEduardo Habkost {
88ca89f720SEduardo Habkost struct soundhw *c;
89ca89f720SEduardo Habkost
909c50b8aaSPaolo Bonzini if (selected) {
91*5ae3ec63STudor Gheorghiu error_report("only one -soundhw option is allowed");
92*5ae3ec63STudor Gheorghiu exit(1);
939c50b8aaSPaolo Bonzini }
949c50b8aaSPaolo Bonzini
95ca89f720SEduardo Habkost for (c = soundhw; c->name; ++c) {
96badf708dSPhilippe Mathieu-Daudé if (g_str_equal(c->name, name)) {
979c50b8aaSPaolo Bonzini selected = c;
98039a6837SPaolo Bonzini audiodev_id = audiodev;
99ca89f720SEduardo Habkost break;
100ca89f720SEduardo Habkost }
101ca89f720SEduardo Habkost }
102ca89f720SEduardo Habkost
103ca89f720SEduardo Habkost if (!c->name) {
104badf708dSPhilippe Mathieu-Daudé error_report("Unknown sound card name `%s'", name);
105eef5fdf3SPaolo Bonzini show_valid_soundhw();
106eef5fdf3SPaolo Bonzini exit(1);
107ca89f720SEduardo Habkost }
108ca89f720SEduardo Habkost }
109ca89f720SEduardo Habkost
soundhw_init(void)1104c565674SEduardo Habkost void soundhw_init(void)
111ca89f720SEduardo Habkost {
1129c50b8aaSPaolo Bonzini struct soundhw *c = selected;
113ca89f720SEduardo Habkost ISABus *isa_bus = (ISABus *) object_resolve_path_type("", TYPE_ISA_BUS, NULL);
114ca89f720SEduardo Habkost PCIBus *pci_bus = (PCIBus *) object_resolve_path_type("", TYPE_PCI_BUS, NULL);
115bf521c56SPaolo Bonzini BusState *bus;
116ca89f720SEduardo Habkost
1179c50b8aaSPaolo Bonzini if (!c) {
1189c50b8aaSPaolo Bonzini return;
1199c50b8aaSPaolo Bonzini }
120ca89f720SEduardo Habkost if (c->isa) {
121bf521c56SPaolo Bonzini if (!isa_bus) {
122bf521c56SPaolo Bonzini error_report("ISA bus not available for %s", c->name);
123bf521c56SPaolo Bonzini exit(1);
124542e0c55SGerd Hoffmann }
125bf521c56SPaolo Bonzini bus = BUS(isa_bus);
126ca89f720SEduardo Habkost } else {
127ca89f720SEduardo Habkost if (!pci_bus) {
128ca89f720SEduardo Habkost error_report("PCI bus not available for %s", c->name);
129ca89f720SEduardo Habkost exit(1);
130ca89f720SEduardo Habkost }
131bf521c56SPaolo Bonzini bus = BUS(pci_bus);
132bf521c56SPaolo Bonzini }
133bf521c56SPaolo Bonzini
134bf521c56SPaolo Bonzini if (c->typename) {
135bf521c56SPaolo Bonzini DeviceState *dev = qdev_new(c->typename);
136039a6837SPaolo Bonzini qdev_prop_set_string(dev, "audiodev", audiodev_id);
137bf521c56SPaolo Bonzini qdev_realize_and_unref(dev, bus, &error_fatal);
138bf521c56SPaolo Bonzini } else {
139bf521c56SPaolo Bonzini assert(!c->isa);
140039a6837SPaolo Bonzini c->init_pci(pci_bus, audiodev_id);
141ca89f720SEduardo Habkost }
142ca89f720SEduardo Habkost }
143ca89f720SEduardo Habkost
144