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 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 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 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 86*badf708dSPhilippe Mathieu-Daudé void select_soundhw(const char *name, const char *audiodev) 87ca89f720SEduardo Habkost { 88ca89f720SEduardo Habkost struct soundhw *c; 89ca89f720SEduardo Habkost 909c50b8aaSPaolo Bonzini if (selected) { 919c50b8aaSPaolo Bonzini error_setg(&error_fatal, "only one -soundhw option is allowed"); 929c50b8aaSPaolo Bonzini } 939c50b8aaSPaolo Bonzini 94ca89f720SEduardo Habkost for (c = soundhw; c->name; ++c) { 95*badf708dSPhilippe Mathieu-Daudé if (g_str_equal(c->name, name)) { 969c50b8aaSPaolo Bonzini selected = c; 97039a6837SPaolo Bonzini audiodev_id = audiodev; 98ca89f720SEduardo Habkost break; 99ca89f720SEduardo Habkost } 100ca89f720SEduardo Habkost } 101ca89f720SEduardo Habkost 102ca89f720SEduardo Habkost if (!c->name) { 103*badf708dSPhilippe Mathieu-Daudé error_report("Unknown sound card name `%s'", name); 104eef5fdf3SPaolo Bonzini show_valid_soundhw(); 105eef5fdf3SPaolo Bonzini exit(1); 106ca89f720SEduardo Habkost } 107ca89f720SEduardo Habkost } 108ca89f720SEduardo Habkost 1094c565674SEduardo Habkost void soundhw_init(void) 110ca89f720SEduardo Habkost { 1119c50b8aaSPaolo Bonzini struct soundhw *c = selected; 112ca89f720SEduardo Habkost ISABus *isa_bus = (ISABus *) object_resolve_path_type("", TYPE_ISA_BUS, NULL); 113ca89f720SEduardo Habkost PCIBus *pci_bus = (PCIBus *) object_resolve_path_type("", TYPE_PCI_BUS, NULL); 114bf521c56SPaolo Bonzini BusState *bus; 115ca89f720SEduardo Habkost 1169c50b8aaSPaolo Bonzini if (!c) { 1179c50b8aaSPaolo Bonzini return; 1189c50b8aaSPaolo Bonzini } 119ca89f720SEduardo Habkost if (c->isa) { 120bf521c56SPaolo Bonzini if (!isa_bus) { 121bf521c56SPaolo Bonzini error_report("ISA bus not available for %s", c->name); 122bf521c56SPaolo Bonzini exit(1); 123542e0c55SGerd Hoffmann } 124bf521c56SPaolo Bonzini bus = BUS(isa_bus); 125ca89f720SEduardo Habkost } else { 126ca89f720SEduardo Habkost if (!pci_bus) { 127ca89f720SEduardo Habkost error_report("PCI bus not available for %s", c->name); 128ca89f720SEduardo Habkost exit(1); 129ca89f720SEduardo Habkost } 130bf521c56SPaolo Bonzini bus = BUS(pci_bus); 131bf521c56SPaolo Bonzini } 132bf521c56SPaolo Bonzini 133bf521c56SPaolo Bonzini if (c->typename) { 134bf521c56SPaolo Bonzini DeviceState *dev = qdev_new(c->typename); 135039a6837SPaolo Bonzini qdev_prop_set_string(dev, "audiodev", audiodev_id); 136bf521c56SPaolo Bonzini qdev_realize_and_unref(dev, bus, &error_fatal); 137bf521c56SPaolo Bonzini } else { 138bf521c56SPaolo Bonzini assert(!c->isa); 139039a6837SPaolo Bonzini c->init_pci(pci_bus, audiodev_id); 140ca89f720SEduardo Habkost } 141ca89f720SEduardo Habkost } 142ca89f720SEduardo Habkost 143