- Set a default PCM volume so that something can be heard when driver is
[AROS.git] / workbench / devs / AHI / Drivers / HDAudio / driver-init.c
blob8dba1753fb26665eca022515d8be2b6b17ce2005
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 ExecBase* SysBase = NULL;
11 struct DosLibrary* DOSBase;
12 #endif
13 #include <stdlib.h>
15 #include "library.h"
16 #include "version.h"
17 #include "pci_wrapper.h"
18 #include "misc.h"
22 struct DriverBase* AHIsubBase;
25 struct VendorDevice
27 UWORD vendor;
28 UWORD device;
32 struct VendorDevice *vendor_device_list = NULL;
33 static int vendor_device_list_size = 0;
35 static void parse_config_file();
36 static int hex_char_to_int(char c);
37 #define MAX_DEVICE_VENDORS 512
40 /******************************************************************************
41 ** Custom driver init *********************************************************
42 ******************************************************************************/
44 BOOL DriverInit(struct DriverBase* ahisubbase)
46 struct HDAudioBase* card_base = (struct HDAudioBase*) ahisubbase;
47 struct PCIDevice *dev;
48 int card_no;
49 int i;
51 bug("ENTERING HDAUDIO!\n");
52 AHIsubBase = ahisubbase;
54 DOSBase = (struct DosLibrary *) OpenLibrary(DOSNAME, 37);
56 if (DOSBase == NULL)
58 Req("Unable to open 'dos.library' version 37.\n");
59 return FALSE;
62 if (!ahi_pci_init(ahisubbase))
64 return FALSE;
67 InitSemaphore(&card_base->semaphore);
69 /*** Count cards ***********************************************************/
71 vendor_device_list = (struct VendorDevice *) AllocVec(sizeof(struct VendorDevice) * MAX_DEVICE_VENDORS, MEMF_PUBLIC | MEMF_CLEAR);
73 // Add Intel ICH7 (used in iMica)
74 vendor_device_list[0].vendor = 0x8086;
75 vendor_device_list[0].device = 0x27D8;
76 vendor_device_list_size++;
78 // Then parse the hdaudio.config file, if available in ENV:
79 parse_config_file();
81 bug("vendor_device_list_size = %ld\n", vendor_device_list_size);
83 card_base->cards_found = 0;
84 dev = NULL;
86 for (i = 0; i < vendor_device_list_size; i++)
88 dev = ahi_pci_find_device(vendor_device_list[i].vendor, vendor_device_list[i].device, dev);
90 if (dev != NULL)
92 bug("Found device with vendor ID = %x, device ID = %x!(i = %d)\n", vendor_device_list[i].vendor, vendor_device_list[i].device, i);
93 ++card_base->cards_found;
94 break; // stop at first found controller
99 FreeVec(vendor_device_list);
101 // Fail if no hardware (prevents the audio modes form being added to
102 // the database if the driver cannot be used).
104 if (card_base->cards_found == 0)
106 bug("No HDaudio controller found! :-(\n");
107 return FALSE;
111 /*** Allocate and init all cards *******************************************/
113 card_base->driverdatas = (struct HDAudioChip **) AllocVec(sizeof(*card_base->driverdatas) * card_base->cards_found, MEMF_PUBLIC);
115 if (card_base->driverdatas == NULL)
117 bug("Out of memory.\n");
118 return FALSE;
121 card_no = 0;
123 if (dev)
125 card_base->driverdatas[card_no] = AllocDriverData(dev, AHIsubBase);
126 if (card_base->driverdatas[card_no] == NULL)
128 return FALSE;
131 ++card_no;
134 bug("exit init\n");
135 return TRUE;
139 /******************************************************************************
140 ** Custom driver clean-up *****************************************************
141 ******************************************************************************/
143 VOID DriverCleanup(struct DriverBase* AHIsubBase)
145 struct HDAudioBase* card_base = (struct HDAudioBase*) AHIsubBase;
146 int i;
148 for(i = 0; i < card_base->cards_found; ++i)
150 FreeDriverData(card_base->driverdatas[i], AHIsubBase);
153 FreeVec(card_base->driverdatas);
155 ahi_pci_exit();
157 if (DOSBase)
159 CloseLibrary((struct Library*) DOSBase);
164 static void parse_config_file()
166 BPTR config_file;
167 BPTR handle;
169 handle = Lock("ENV:hdaudio.config", SHARED_LOCK);
171 if (handle == 0)
173 bug("No handle found\n");
174 return;
177 UnLock(handle);
179 config_file = Open("ENV:hdaudio.config", MODE_OLDFILE);
181 if (config_file)
183 BOOL Continue = TRUE;
184 bug("Opened config file\n");
186 while (Continue)
188 char *line = (char *) AllocVec(512, MEMF_CLEAR);
189 char *ret;
191 ret = FGets(config_file, line, 512);
193 if (ret == NULL)
195 FreeVec(line);
196 break;
199 if (ret[0] == '0' &&
200 ret[1] == 'x' &&
201 ret[6] == ',' &&
202 ret[7] == ' ' &&
203 ret[8] == '0' &&
204 ret[9] == 'x' &&
205 ret[15] == '\0')
207 int value;
208 UWORD vendor, device;
209 char *tmp = (char *) AllocVec(16, MEMF_CLEAR);
210 char *tmp2 = (char *) AllocVec(4, MEMF_CLEAR);
212 CopyMem(line + 2, tmp, 4);
213 tmp[4] = '\0';
215 // convert hex to decimal
216 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]);
217 vendor = (UWORD) value;
219 CopyMem(line + 10, tmp, 4);
220 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]);
221 device = (UWORD) value;
222 //bug("Adding vendor = %x, device = %x to list, size = %ld\n", vendor, device, vendor_device_list_size);
224 vendor_device_list[vendor_device_list_size].vendor = vendor;
225 vendor_device_list[vendor_device_list_size].device = device;
226 vendor_device_list_size++;
228 if (vendor_device_list_size >= MAX_DEVICE_VENDORS)
230 bug("Exceeded MAX_DEVICE_VENDORS\n");
231 break;
234 FreeVec(tmp);
235 FreeVec(tmp2);
237 else if (ret[0] == 'Q' && ret[1] == 'U' && ret[2] == 'E' && ret[3] == 'R' && ret[4] == 'Y')
239 bug("QUERY found!\n");
240 setForceQuery();
242 if (ret[5] == 'D') // debug
244 setDumpAll();
247 else if (Strnicmp(ret, "speaker=0x", 10) == 0)
249 int speaker = 0;
250 char *tmp = (char *) AllocVec(16, MEMF_CLEAR);
252 CopyMem(line + 10, tmp, 2);
253 tmp[2] = '\0';
255 // convert hex to decimal
256 speaker = hex_char_to_int(tmp[0]) * 16 + hex_char_to_int(tmp[1]);
258 bug("Speaker in config = %x!\n", speaker);
260 setForceSpeaker(speaker);
263 FreeVec(line);
266 Close(config_file);
268 else
270 bug("Couldn't open config file!\n");
275 static int hex_char_to_int(char c)
277 if (c >= '0' && c <= '9')
279 return (c - '0');
281 else if (c >= 'A' && c <= 'F')
283 return 10 + (c - 'A');
285 else if (c >= 'a' && c <= 'f')
287 return 10 + (c - 'a');
289 else
291 bug("Error in hex_char_to_int: char was %c\n", c);
292 return 0;