1 /* 2 * Copyright 2007-2008, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Ithamar Adema, ithamar AT unet DOT nl 7 */ 8 9 10 #include "driver.h" 11 12 13 int32 api_version = B_CUR_DRIVER_API_VERSION; 14 15 hda_controller gCards[MAX_CARDS]; 16 uint32 gNumCards; 17 pci_module_info* gPci; 18 19 20 extern "C" status_t 21 init_hardware(void) 22 { 23 pci_info info; 24 long i; 25 26 if (get_module(B_PCI_MODULE_NAME, (module_info**)&gPci) != B_OK) 27 return ENODEV; 28 29 for (i = 0; gPci->get_nth_pci_info(i, &info) == B_OK; i++) { 30 if (info.class_base == PCI_multimedia 31 && info.class_sub == PCI_hd_audio) { 32 put_module(B_PCI_MODULE_NAME); 33 return B_OK; 34 } 35 } 36 37 put_module(B_PCI_MODULE_NAME); 38 return ENODEV; 39 } 40 41 42 extern "C" status_t 43 init_driver(void) 44 { 45 char path[B_PATH_NAME_LENGTH]; 46 pci_info info; 47 long i; 48 49 if (get_module(B_PCI_MODULE_NAME, (module_info**)&gPci) != B_OK) 50 return ENODEV; 51 52 gNumCards = 0; 53 54 for (i = 0; gPci->get_nth_pci_info(i, &info) == B_OK 55 && gNumCards < MAX_CARDS; i++) { 56 if (info.class_base == PCI_multimedia 57 && info.class_sub == PCI_hd_audio) { 58 #ifdef __HAIKU__ 59 if ((*gPci->reserve_device)(info.bus, info.device, info.function, "hda", 60 &gCards[gNumCards]) < B_OK) { 61 dprintf("HDA: Failed to reserve PCI:%d:%d:%d\n", 62 info.bus, info.device, info.function); 63 continue; 64 } 65 #endif 66 memset(&gCards[gNumCards], 0, sizeof(hda_controller)); 67 gCards[gNumCards].pci_info = info; 68 gCards[gNumCards].opened = 0; 69 sprintf(path, DEVFS_PATH_FORMAT, gNumCards); 70 gCards[gNumCards++].devfs_path = strdup(path); 71 72 dprintf("HDA: Detected controller @ PCI:%d:%d:%d, IRQ:%d, type %04x/%04x (%04x/%04x)\n", 73 info.bus, info.device, info.function, 74 info.u.h0.interrupt_line, 75 info.vendor_id, info.device_id, 76 info.u.h0.subsystem_vendor_id, info.u.h0.subsystem_id); 77 } 78 } 79 80 if (gNumCards == 0) { 81 put_module(B_PCI_MODULE_NAME); 82 return ENODEV; 83 } 84 85 return B_OK; 86 } 87 88 89 extern "C" void 90 uninit_driver(void) 91 { 92 dprintf("IRA: %s\n", __func__); 93 94 for (uint32 i = 0; i < gNumCards; i++) { 95 #ifdef __HAIKU__ 96 (*gPci->unreserve_device)(gCards[i].pci_info.bus, gCards[i].pci_info.device, 97 gCards[i].pci_info.function, "hda", &gCards[i]); 98 #endif 99 free((void*)gCards[i].devfs_path); 100 gCards[i].devfs_path = NULL; 101 } 102 103 put_module(B_PCI_MODULE_NAME); 104 } 105 106 107 extern "C" const char** 108 publish_devices(void) 109 { 110 static const char* devs[MAX_CARDS + 1]; 111 uint32 i; 112 113 dprintf("IRA: %s\n", __func__); 114 for (i = 0; i < gNumCards; i++) { 115 devs[i] = gCards[i].devfs_path; 116 } 117 118 devs[i] = NULL; 119 120 return devs; 121 } 122 123 124 extern "C" device_hooks* 125 find_device(const char* name) 126 { 127 dprintf("IRA: %s\n", __func__); 128 return &gDriverHooks; 129 } 130