Build for AROS..
[AROS.git] / workbench / devs / AHI / Drivers / HDAudio / driver-init.c
blob1c514a6075b147b8e00362d6c4753d86b75b3d93
2 #include <exec/memory.h>
4 #include <proto/expansion.h>
5 #include <proto/dos.h>
6 #include <proto/exec.h>
7 #include <clib/alib_protos.h>
8 #ifdef __AROS__
9 #include <aros/debug.h>
10 struct DosLibrary* DOSBase;
11 #endif
12 #include <stdlib.h>
14 #include "library.h"
15 #include "version.h"
16 #include "pci_wrapper.h"
17 #include "misc.h"
21 struct DriverBase* AHIsubBase;
24 struct VendorDevice
26 UWORD vendor;
27 UWORD device;
31 struct VendorDevice *vendor_device_list = NULL;
32 static int vendor_device_list_size = 0;
34 static void parse_config_file();
35 static int hex_char_to_int(char c);
36 #define MAX_DEVICE_VENDORS 512
39 /******************************************************************************
40 ** Custom driver init *********************************************************
41 ******************************************************************************/
43 BOOL DriverInit(struct DriverBase* ahisubbase)
45 struct HDAudioBase* card_base = (struct HDAudioBase*) ahisubbase;
46 struct PCIDevice *dev;
47 int card_no;
48 int i;
50 bug("ENTERING HDAUDIO!\n");
51 AHIsubBase = ahisubbase;
53 DOSBase = (struct DosLibrary *) OpenLibrary(DOSNAME, 37);
55 if (DOSBase == NULL)
57 Req("Unable to open 'dos.library' version 37.\n");
58 return FALSE;
61 if (!ahi_pci_init(ahisubbase))
63 return FALSE;
66 InitSemaphore(&card_base->semaphore);
68 /*** Count cards ***********************************************************/
70 vendor_device_list = (struct VendorDevice *) AllocVec(sizeof(struct VendorDevice) * MAX_DEVICE_VENDORS, MEMF_PUBLIC | MEMF_CLEAR);
72 // Add Intel ICH7 (used in iMica)
73 vendor_device_list[0].vendor = 0x8086;
74 vendor_device_list[0].device = 0x27D8;
75 vendor_device_list_size++;
77 // Then parse the hdaudio.config file, if available in ENV:
78 parse_config_file();
80 bug("vendor_device_list_size = %ld\n", vendor_device_list_size);
82 card_base->cards_found = 0;
83 dev = NULL;
85 for (i = 0; i < vendor_device_list_size; i++)
87 dev = ahi_pci_find_device(vendor_device_list[i].vendor, vendor_device_list[i].device, dev);
89 if (dev != NULL)
91 bug("Found device with vendor ID = %x, device ID = %x!(i = %d)\n", vendor_device_list[i].vendor, vendor_device_list[i].device, i);
92 ++card_base->cards_found;
93 break; // stop at first found controller
98 FreeVec(vendor_device_list);
100 // Fail if no hardware (prevents the audio modes form being added to
101 // the database if the driver cannot be used).
103 if (card_base->cards_found == 0)
105 bug("No HDaudio controller found! :-(\n");
106 return FALSE;
110 /*** Allocate and init all cards *******************************************/
112 card_base->driverdatas = (struct HDAudioChip **) AllocVec(sizeof(*card_base->driverdatas) * card_base->cards_found, MEMF_PUBLIC);
114 if (card_base->driverdatas == NULL)
116 bug("Out of memory.\n");
117 return FALSE;
120 card_no = 0;
122 if (dev)
124 card_base->driverdatas[card_no] = AllocDriverData(dev, AHIsubBase);
125 if (card_base->driverdatas[card_no] == NULL)
127 return FALSE;
130 ++card_no;
133 bug("exit init\n");
134 return TRUE;
138 /******************************************************************************
139 ** Custom driver clean-up *****************************************************
140 ******************************************************************************/
142 VOID DriverCleanup(struct DriverBase* AHIsubBase)
144 struct HDAudioBase* card_base = (struct HDAudioBase*) AHIsubBase;
145 int i;
147 for(i = 0; i < card_base->cards_found; ++i)
149 FreeDriverData(card_base->driverdatas[i], AHIsubBase);
152 FreeVec(card_base->driverdatas);
154 ahi_pci_exit();
156 if (DOSBase)
158 CloseLibrary((struct Library*) DOSBase);
163 static void parse_config_file()
165 BPTR config_file;
166 BPTR handle;
168 handle = Lock("ENV:hdaudio.config", SHARED_LOCK);
170 if (handle == 0)
172 bug("No handle found\n");
173 return;
176 UnLock(handle);
178 config_file = Open("ENV:hdaudio.config", MODE_OLDFILE);
180 if (config_file)
182 BOOL Continue = TRUE;
183 bug("Opened config file\n");
185 while (Continue)
187 char *line = (char *) AllocVec(512, MEMF_CLEAR);
188 char *ret;
190 ret = FGets(config_file, line, 512);
192 if (ret == NULL)
194 FreeVec(line);
195 break;
198 if (ret[0] == '0' &&
199 ret[1] == 'x' &&
200 ret[6] == ',' &&
201 ret[7] == ' ' &&
202 ret[8] == '0' &&
203 ret[9] == 'x' &&
204 ret[15] == '\0')
206 int value;
207 UWORD vendor, device;
208 char *tmp = (char *) AllocVec(16, MEMF_CLEAR);
209 char *tmp2 = (char *) AllocVec(4, MEMF_CLEAR);
211 CopyMem(line + 2, tmp, 4);
212 tmp[4] = '\0';
214 // convert hex to decimal
215 value = hex_char_to_int(tmp[0]) * 16 * 16 * 16 + hex_char_to_int(tmp[1]) * 16 * 16 + hex_char_to_int(tmp[2]) * 16 + hex_char_to_int(tmp[3]);
216 vendor = (UWORD) value;
218 CopyMem(line + 10, tmp, 4);
219 value = hex_char_to_int(tmp[0]) * 16 * 16 * 16 + hex_char_to_int(tmp[1]) * 16 * 16 + hex_char_to_int(tmp[2]) * 16 + hex_char_to_int(tmp[3]);
220 device = (UWORD) value;
221 //bug("Adding vendor = %x, device = %x to list, size = %ld\n", vendor, device, vendor_device_list_size);
223 vendor_device_list[vendor_device_list_size].vendor = vendor;
224 vendor_device_list[vendor_device_list_size].device = device;
225 vendor_device_list_size++;
227 if (vendor_device_list_size >= MAX_DEVICE_VENDORS)
229 bug("Exceeded MAX_DEVICE_VENDORS\n");
230 break;
233 FreeVec(tmp);
234 FreeVec(tmp2);
236 else if (ret[0] == 'Q' && ret[1] == 'U' && ret[2] == 'E' && ret[3] == 'R' && ret[4] == 'Y')
238 bug("QUERY found!\n");
239 setForceQuery();
241 if (ret[5] == 'D') // debug
243 setDumpAll();
246 else if (Strnicmp(ret, "speaker=0x", 10) == 0)
248 int speaker = 0;
249 char *tmp = (char *) AllocVec(16, MEMF_CLEAR);
251 CopyMem(line + 10, tmp, 2);
252 tmp[2] = '\0';
254 // convert hex to decimal
255 speaker = hex_char_to_int(tmp[0]) * 16 + hex_char_to_int(tmp[1]);
257 bug("Speaker in config = %x!\n", speaker);
259 setForceSpeaker(speaker);
262 FreeVec(line);
265 Close(config_file);
267 else
269 bug("Couldn't open config file!\n");
274 static int hex_char_to_int(char c)
276 if (c >= '0' && c <= '9')
278 return (c - '0');
280 else if (c >= 'A' && c <= 'F')
282 return 10 + (c - 'A');
284 else if (c >= 'a' && c <= 'f')
286 return 10 + (c - 'a');
288 else
290 bug("Error in hex_char_to_int: char was %c\n", c);
291 return 0;