BPicture: Fix archive constructor.
[haiku.git] / src / add-ons / kernel / drivers / audio / ac97 / sis7018 / Driver.cpp
blobf0b2d318d575532f114dae78579e98b71595b5b9
1 /*
2 * SiS 7018, Trident 4D Wave DX/NX, Acer Lab M5451 Sound Driver.
3 * Copyright (c) 2002, 2008-2011 S.Zharski <imker@gmx.li>
4 * Distributed under the terms of the MIT license.
6 */
9 #include "Driver.h"
11 #include <kernel_cpp.h>
12 #include <string.h>
14 #include "Device.h"
15 #include "Settings.h"
18 int32 api_version = B_CUR_DRIVER_API_VERSION;
20 size_t gNumCards = 0;
21 Device *gDevices[MAX_DEVICES] = { 0 };
22 char *gDeviceNames[MAX_DEVICES + 1] = { 0 };
23 pci_module_info *gPCI = NULL;
26 static Device::Info cardInfos[] = {
27 { SiS7018, "SiS 7018" },
28 { ALi5451, "ALi M5451" },
29 { TridentDX, "Trident DX" },
30 { TridentNX, "Trident NX" }
34 status_t
35 init_hardware()
37 dprintf("sis7018:init_hardware:ver:%s\n", kVersion);
38 status_t result = get_module(B_PCI_MODULE_NAME, (module_info **)&gPCI);
39 if (result < B_OK) {
40 return ENOSYS;
43 pci_info info = {0};
44 for (long i = 0; B_OK == (*gPCI->get_nth_pci_info)(i, &info); i++) {
45 for (size_t idx = 0; idx < B_COUNT_OF(cardInfos); idx++) {
46 if (info.vendor_id == cardInfos[idx].VendorId() &&
47 info.device_id == cardInfos[idx].DeviceId())
49 put_module(B_PCI_MODULE_NAME);
50 return B_OK;
55 put_module(B_PCI_MODULE_NAME);
56 return ENODEV;
60 status_t
61 init_driver()
63 status_t status = get_module(B_PCI_MODULE_NAME, (module_info **)&gPCI);
64 if (status < B_OK) {
65 return ENOSYS;
68 load_settings();
70 pci_info info = { 0 };
71 for (long i = 0; B_OK == (*gPCI->get_nth_pci_info)(i, &info); i++) {
72 for (size_t idx = 0; idx < B_COUNT_OF(cardInfos); idx++) {
73 if (info.vendor_id == cardInfos[idx].VendorId() &&
74 info.device_id == cardInfos[idx].DeviceId())
76 if (gNumCards == MAX_DEVICES) {
77 ERROR("Skipped:%s [%#06x:%#06x]\n", cardInfos[idx].Name(),
78 cardInfos[idx].VendorId(), cardInfos[idx].DeviceId());
79 break;
82 Device* device = new Device(cardInfos[idx], info);
83 if (device == 0) {
84 return ENODEV;
87 status_t status = device->InitCheck();
88 if (status < B_OK) {
89 delete device;
90 break;
93 status = device->Setup();
94 if (status < B_OK) {
95 delete device;
96 break;
99 char name[32] = {0};
100 sprintf(name, "audio/hmulti/%s/%ld",
101 cardInfos[idx].Name(), gNumCards);
102 gDeviceNames[gNumCards] = strdup(name);
103 gDevices[gNumCards++] = device;
105 TRACE("Found:%s [%#06x:%#06x]\n", cardInfos[idx].Name(),
106 cardInfos[idx].VendorId(), cardInfos[idx].DeviceId());
111 if (gNumCards == 0) {
112 put_module(B_PCI_MODULE_NAME);
113 return ENODEV;
116 return B_OK;
120 void
121 uninit_driver()
123 for (size_t i = 0; i < MAX_DEVICES; i++) {
124 if (gDevices[i]) {
125 delete gDevices[i];
126 gDevices[i] = NULL;
129 free(gDeviceNames[i]);
130 gDeviceNames[i] = NULL;
133 put_module(B_PCI_MODULE_NAME);
135 release_settings();
139 static status_t
140 SiS7018_open(const char *name, uint32 flags, void **cookie)
142 status_t status = ENODEV;
143 *cookie = NULL;
144 for (size_t i = 0; i < MAX_DEVICES; i++) {
145 if (gDeviceNames[i] && !strcmp(gDeviceNames[i], name)) {
146 status = gDevices[i]->Open(flags);
147 *cookie = gDevices[i];
151 return status;
155 static status_t
156 SiS7018_read(void *cookie, off_t position, void *buffer, size_t *numBytes)
158 Device *device = (Device *)cookie;
159 return device->Read((uint8 *)buffer, numBytes);
163 static status_t
164 SiS7018_write(void *cookie, off_t position,
165 const void *buffer, size_t *numBytes)
167 Device *device = (Device *)cookie;
168 return device->Write((const uint8 *)buffer, numBytes);
172 static status_t
173 SiS7018_control(void *cookie, uint32 op, void *buffer, size_t length)
175 Device *device = (Device *)cookie;
176 return device->Control(op, buffer, length);
180 static status_t
181 SiS7018_close(void *cookie)
183 Device *device = (Device *)cookie;
184 return device->Close();
188 static status_t
189 SiS7018_free(void *cookie)
191 Device *device = (Device *)cookie;
192 return device->Free();
196 const char **
197 publish_devices()
199 for (size_t i = 0; i < MAX_DEVICES; i++) {
200 if (gDevices[i] == NULL)
201 continue;
203 if (gDeviceNames[i])
204 TRACE("%s\n", gDeviceNames[i]);
207 return (const char **)&gDeviceNames[0];
211 device_hooks *
212 find_device(const char *name)
214 static device_hooks deviceHooks = {
215 SiS7018_open,
216 SiS7018_close,
217 SiS7018_free,
218 SiS7018_control,
219 SiS7018_read,
220 SiS7018_write,
221 NULL, // select
222 NULL // deselect
225 return &deviceHooks;