xref: /haiku/src/add-ons/kernel/drivers/audio/ac97/geode/driver.cpp (revision cbe0a0c436162d78cc3f92a305b64918c839d079)
1 /*
2  * Copyright 2009, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *	Jérôme Duval (korli@users.berlios.de)
7  */
8 
9 
10 #include "driver.h"
11 
12 
13 int32 api_version = B_CUR_DRIVER_API_VERSION;
14 
15 geode_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.vendor_id == AMD_VENDOR_ID
31 			&& info.device_id == AMD_CS5536_AUDIO_DEVICE_ID)
32 			|| (info.vendor_id == NS_VENDOR_ID
33 				&& info.device_id == NS_CS5535_AUDIO_DEVICE_ID)) {
34 			put_module(B_PCI_MODULE_NAME);
35 			return B_OK;
36 		}
37 	}
38 
39 	put_module(B_PCI_MODULE_NAME);
40 	return ENODEV;
41 }
42 
43 
44 extern "C" status_t
45 init_driver(void)
46 {
47 	char path[B_PATH_NAME_LENGTH];
48 	pci_info info;
49 	long i;
50 
51 	if (get_module(B_PCI_MODULE_NAME, (module_info**)&gPci) != B_OK)
52 		return ENODEV;
53 
54 	gNumCards = 0;
55 
56 	for (i = 0; gPci->get_nth_pci_info(i, &info) == B_OK
57 			&& gNumCards < MAX_CARDS; i++) {
58 		if ((info.vendor_id == AMD_VENDOR_ID
59 			&& info.device_id == AMD_CS5536_AUDIO_DEVICE_ID)
60 			|| (info.vendor_id == NS_VENDOR_ID
61 				&& info.device_id == NS_CS5535_AUDIO_DEVICE_ID)) {
62 			memset(&gCards[gNumCards], 0, sizeof(geode_controller));
63 			gCards[gNumCards].pci_info = info;
64 			gCards[gNumCards].opened = 0;
65 			sprintf(path, DEVFS_PATH_FORMAT, gNumCards);
66 			gCards[gNumCards++].devfs_path = strdup(path);
67 
68 			dprintf("geode: detected controller @ PCI:%d:%d:%d, IRQ:%d, type %04x/%04x\n",
69 				info.bus, info.device, info.function,
70 				info.u.h0.interrupt_line,
71 				info.vendor_id, info.device_id);
72 		}
73 	}
74 
75 	if (gNumCards == 0) {
76 		put_module(B_PCI_MODULE_NAME);
77 		return ENODEV;
78 	}
79 
80 	return B_OK;
81 }
82 
83 
84 extern "C" void
85 uninit_driver(void)
86 {
87 	for (uint32 i = 0; i < gNumCards; i++) {
88 		free((void*)gCards[i].devfs_path);
89 		gCards[i].devfs_path = NULL;
90 	}
91 
92 	put_module(B_PCI_MODULE_NAME);
93 }
94 
95 
96 extern "C" const char**
97 publish_devices(void)
98 {
99 	static const char* devs[MAX_CARDS + 1];
100 	uint32 i;
101 
102 	for (i = 0; i < gNumCards; i++) {
103 		devs[i] = gCards[i].devfs_path;
104 	}
105 
106 	devs[i] = NULL;
107 
108 	return devs;
109 }
110 
111 
112 extern "C" device_hooks*
113 find_device(const char* name)
114 {
115 	return &gDriverHooks;
116 }
117