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
13int32 api_version = B_CUR_DRIVER_API_VERSION;
14
15geode_controller gCards[MAX_CARDS];
16uint32 gNumCards;
17pci_module_info* gPci;
18
19
20extern "C" status_t
21init_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
44extern "C" status_t
45init_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
84extern "C" void
85uninit_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
96extern "C" const char**
97publish_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
112extern "C" device_hooks*
113find_device(const char* name)
114{
115	return &gDriverHooks;
116}
117