xref: /qemu/hw/audio/soundhw.c (revision eef5fdf3d57dccc25505179f717adf636764ba02)
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"
30ca89f720SEduardo Habkost #include "hw/isa/isa.h"
31ca89f720SEduardo Habkost #include "hw/pci/pci.h"
328a824e4dSEduardo Habkost #include "hw/audio/soundhw.h"
33ca89f720SEduardo Habkost 
34ca89f720SEduardo Habkost struct soundhw {
35ca89f720SEduardo Habkost     const char *name;
36ca89f720SEduardo Habkost     const char *descr;
37542e0c55SGerd Hoffmann     const char *typename;
38ca89f720SEduardo Habkost     int isa;
39ca89f720SEduardo Habkost     int (*init_pci) (PCIBus *bus);
40ca89f720SEduardo Habkost };
41ca89f720SEduardo Habkost 
42ca89f720SEduardo Habkost static struct soundhw soundhw[9];
43ca89f720SEduardo Habkost static int soundhw_count;
44ca89f720SEduardo Habkost 
45ca89f720SEduardo Habkost void pci_register_soundhw(const char *name, const char *descr,
46ca89f720SEduardo Habkost                           int (*init_pci)(PCIBus *bus))
47ca89f720SEduardo Habkost {
48ca89f720SEduardo Habkost     assert(soundhw_count < ARRAY_SIZE(soundhw) - 1);
49ca89f720SEduardo Habkost     soundhw[soundhw_count].name = name;
50ca89f720SEduardo Habkost     soundhw[soundhw_count].descr = descr;
51ca89f720SEduardo Habkost     soundhw[soundhw_count].isa = 0;
526033b9ecSPaolo Bonzini     soundhw[soundhw_count].init_pci = init_pci;
53ca89f720SEduardo Habkost     soundhw_count++;
54ca89f720SEduardo Habkost }
55ca89f720SEduardo Habkost 
56542e0c55SGerd Hoffmann void deprecated_register_soundhw(const char *name, const char *descr,
57542e0c55SGerd Hoffmann                                  int isa, const char *typename)
58542e0c55SGerd Hoffmann {
59542e0c55SGerd Hoffmann     assert(soundhw_count < ARRAY_SIZE(soundhw) - 1);
60542e0c55SGerd Hoffmann     soundhw[soundhw_count].name = name;
61542e0c55SGerd Hoffmann     soundhw[soundhw_count].descr = descr;
62542e0c55SGerd Hoffmann     soundhw[soundhw_count].isa = isa;
63542e0c55SGerd Hoffmann     soundhw[soundhw_count].typename = typename;
64542e0c55SGerd Hoffmann     soundhw_count++;
65542e0c55SGerd Hoffmann }
66542e0c55SGerd Hoffmann 
67*eef5fdf3SPaolo Bonzini void show_valid_soundhw(void)
68*eef5fdf3SPaolo Bonzini {
69*eef5fdf3SPaolo Bonzini     struct soundhw *c;
70*eef5fdf3SPaolo Bonzini 
71*eef5fdf3SPaolo Bonzini     if (soundhw_count) {
72*eef5fdf3SPaolo Bonzini          printf("Valid sound card names (comma separated):\n");
73*eef5fdf3SPaolo Bonzini          for (c = soundhw; c->name; ++c) {
74*eef5fdf3SPaolo Bonzini              printf ("%-11s %s\n", c->name, c->descr);
75*eef5fdf3SPaolo Bonzini          }
76*eef5fdf3SPaolo Bonzini     } else {
77*eef5fdf3SPaolo Bonzini          printf("Machine has no user-selectable audio hardware "
78*eef5fdf3SPaolo Bonzini                 "(it may or may not have always-present audio hardware).\n");
79*eef5fdf3SPaolo Bonzini     }
80*eef5fdf3SPaolo Bonzini }
81*eef5fdf3SPaolo Bonzini 
829c50b8aaSPaolo Bonzini static struct soundhw *selected = NULL;
839c50b8aaSPaolo Bonzini 
84ca89f720SEduardo Habkost void select_soundhw(const char *optarg)
85ca89f720SEduardo Habkost {
86ca89f720SEduardo Habkost     struct soundhw *c;
87ca89f720SEduardo Habkost 
889c50b8aaSPaolo Bonzini     if (selected) {
899c50b8aaSPaolo Bonzini         error_setg(&error_fatal, "only one -soundhw option is allowed");
909c50b8aaSPaolo Bonzini     }
919c50b8aaSPaolo Bonzini 
92ca89f720SEduardo Habkost     if (is_help_option(optarg)) {
93*eef5fdf3SPaolo Bonzini         show_valid_soundhw();
94*eef5fdf3SPaolo Bonzini         exit(0);
95ca89f720SEduardo Habkost     }
96ca89f720SEduardo Habkost     else {
97ca89f720SEduardo Habkost         for (c = soundhw; c->name; ++c) {
989c50b8aaSPaolo Bonzini             if (g_str_equal(c->name, optarg)) {
999c50b8aaSPaolo Bonzini                 selected = c;
100ca89f720SEduardo Habkost                 break;
101ca89f720SEduardo Habkost             }
102ca89f720SEduardo Habkost         }
103ca89f720SEduardo Habkost 
104ca89f720SEduardo Habkost         if (!c->name) {
1059c50b8aaSPaolo Bonzini             error_report("Unknown sound card name `%s'", optarg);
106*eef5fdf3SPaolo Bonzini             show_valid_soundhw();
107*eef5fdf3SPaolo Bonzini             exit(1);
108ca89f720SEduardo Habkost         }
109ca89f720SEduardo Habkost     }
110ca89f720SEduardo Habkost }
111ca89f720SEduardo Habkost 
1124c565674SEduardo Habkost void soundhw_init(void)
113ca89f720SEduardo Habkost {
1149c50b8aaSPaolo Bonzini     struct soundhw *c = selected;
115ca89f720SEduardo Habkost     ISABus *isa_bus = (ISABus *) object_resolve_path_type("", TYPE_ISA_BUS, NULL);
116ca89f720SEduardo Habkost     PCIBus *pci_bus = (PCIBus *) object_resolve_path_type("", TYPE_PCI_BUS, NULL);
117ca89f720SEduardo Habkost 
1189c50b8aaSPaolo Bonzini     if (!c) {
1199c50b8aaSPaolo Bonzini         return;
1209c50b8aaSPaolo Bonzini     }
121542e0c55SGerd Hoffmann     if (c->typename) {
122542e0c55SGerd Hoffmann         warn_report("'-soundhw %s' is deprecated, "
123542e0c55SGerd Hoffmann                     "please use '-device %s' instead",
124542e0c55SGerd Hoffmann                     c->name, c->typename);
125ca89f720SEduardo Habkost         if (c->isa) {
126542e0c55SGerd Hoffmann             isa_create_simple(isa_bus, c->typename);
127542e0c55SGerd Hoffmann         } else {
128542e0c55SGerd Hoffmann             pci_create_simple(pci_bus, -1, c->typename);
129542e0c55SGerd Hoffmann         }
130ca89f720SEduardo Habkost     } else {
1316033b9ecSPaolo Bonzini         assert(!c->isa);
132ca89f720SEduardo Habkost         if (!pci_bus) {
133ca89f720SEduardo Habkost             error_report("PCI bus not available for %s", c->name);
134ca89f720SEduardo Habkost             exit(1);
135ca89f720SEduardo Habkost         }
1366033b9ecSPaolo Bonzini         c->init_pci(pci_bus);
137ca89f720SEduardo Habkost     }
138ca89f720SEduardo Habkost }
139ca89f720SEduardo Habkost 
140