xref: /haiku/src/add-ons/kernel/drivers/audio/hda/driver.cpp (revision b671e9bbdbd10268a042b4f4cc4317ccd03d105e)
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