grub2: bring back build of aros-side grub2 tools
[AROS.git] / workbench / devs / AHI / Drivers / HDAudio / driver-init.c
bloba9a27b123292eccf6118d039180edd89c5686752
1 /*
2 The contents of this file are subject to the AROS Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
3 http://www.aros.org/license.html
5 Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
6 ANY KIND, either express or implied. See the License for the specific language governing rights and
7 limitations under the License.
9 (C) Copyright xxxx-2009 Davy Wentzler.
10 (C) Copyright 2009-2010 Stephen Jones.
12 The Initial Developer of the Original Code is Davy Wentzler.
14 All Rights Reserved.
17 #include <exec/memory.h>
19 #include <proto/expansion.h>
20 #include <proto/dos.h>
21 #include <proto/exec.h>
22 #include <clib/alib_protos.h>
23 #ifdef __AROS__
24 #include <aros/debug.h>
25 struct DosLibrary* DOSBase;
26 struct Library *StdCBase = NULL;
27 #endif
28 #include <stdlib.h>
30 #include "library.h"
31 #include "version.h"
32 #include "pci_wrapper.h"
33 #include "misc.h"
37 struct DriverBase* AHIsubBase;
40 struct VendorDevice
42 UWORD vendor;
43 UWORD device;
47 struct VendorDevice *vendor_device_list = NULL;
48 static int vendor_device_list_size = 0;
50 static void parse_config_file(void);
51 static int hex_char_to_int(char c);
52 #define MAX_DEVICE_VENDORS 512
55 /******************************************************************************
56 ** Custom driver init *********************************************************
57 ******************************************************************************/
59 BOOL DriverInit(struct DriverBase* ahisubbase)
61 struct HDAudioBase* card_base = (struct HDAudioBase*) ahisubbase;
62 struct PCIDevice *dev;
63 int card_no;
64 int i;
66 D(bug("[HDAudio] %s()\n", __PRETTY_FUNCTION__));
67 AHIsubBase = ahisubbase;
69 DOSBase = (struct DosLibrary *) OpenLibrary(DOSNAME, 37);
71 if (DOSBase == NULL)
73 Req("Unable to open 'dos.library' version 37.\n");
74 return FALSE;
77 #ifdef __AROS__
78 StdCBase = OpenLibrary("stdc.library", 0);
79 if (StdCBase == NULL)
81 Req("Unable to open 'stdc.library'.\n");
82 return FALSE;
84 #endif
86 if (!ahi_pci_init(ahisubbase))
88 return FALSE;
91 InitSemaphore(&card_base->semaphore);
93 /*** Count cards ***********************************************************/
95 vendor_device_list = (struct VendorDevice *) AllocVec(sizeof(struct VendorDevice) * MAX_DEVICE_VENDORS, MEMF_PUBLIC | MEMF_CLEAR);
97 // Add Intel ICH7 (used in iMica)
98 vendor_device_list[0].vendor = 0x8086;
99 vendor_device_list[0].device = 0x27D8;
100 vendor_device_list_size++;
102 // Then parse the hdaudio.config file, if available in ENV:
103 parse_config_file();
105 D(bug("[HDAudio] vendor_device_list_size = %ld\n", vendor_device_list_size));
107 card_base->cards_found = 0;
108 dev = NULL;
110 for (i = 0; i < vendor_device_list_size; i++)
112 dev = ahi_pci_find_device(vendor_device_list[i].vendor, vendor_device_list[i].device, dev);
114 if (dev != NULL)
116 D(bug("[HDAudio] Found device with vendor ID = %x, device ID = %x!(i = %d)\n", vendor_device_list[i].vendor, vendor_device_list[i].device, i));
117 ++card_base->cards_found;
118 break; // stop at first found controller
123 FreeVec(vendor_device_list);
125 // Fail if no hardware (prevents the audio modes from being added to
126 // the database if the driver cannot be used).
128 if (card_base->cards_found == 0)
130 D(bug("[HDAudio] No HDaudio controller found! :-(\n"));
131 return FALSE;
135 /*** Allocate and init all cards *******************************************/
137 card_base->driverdatas = (struct HDAudioChip **) AllocVec(
138 sizeof(*card_base->driverdatas) * card_base->cards_found,
139 MEMF_PUBLIC | MEMF_CLEAR);
141 if (card_base->driverdatas == NULL)
143 D(bug("[HDAudio] Out of memory.\n"));
144 return FALSE;
147 card_no = 0;
149 if (dev)
151 card_base->driverdatas[card_no] = AllocDriverData(dev, AHIsubBase);
152 if (card_base->driverdatas[card_no] == NULL)
154 FreeVec(card_base->driverdatas);
155 return FALSE;
158 ++card_no;
161 D(bug("[HDAudio] exit init\n"));
162 return TRUE;
166 /******************************************************************************
167 ** Custom driver clean-up *****************************************************
168 ******************************************************************************/
170 VOID DriverCleanup(struct DriverBase* AHIsubBase)
172 struct HDAudioBase* card_base = (struct HDAudioBase*) AHIsubBase;
173 int i;
175 for(i = 0; i < card_base->cards_found; ++i)
177 FreeDriverData(card_base->driverdatas[i], AHIsubBase);
180 FreeVec(card_base->driverdatas);
182 ahi_pci_exit();
184 #ifdef __AROS__
185 if (StdCBase)
187 CloseLibrary(StdCBase);
189 #endif
191 if (DOSBase)
193 CloseLibrary((struct Library*) DOSBase);
198 static void parse_config_file(void)
200 BPTR config_file;
201 BPTR handle;
203 handle = Lock("ENV:hdaudio.config", SHARED_LOCK);
205 if (handle == 0)
207 bug("No handle found\n");
208 return;
211 UnLock(handle);
213 config_file = Open("ENV:hdaudio.config", MODE_OLDFILE);
215 if (config_file)
217 BOOL Continue = TRUE;
218 bug("Opened config file\n");
220 while (Continue)
222 char *line = (char *) AllocVec(512, MEMF_CLEAR);
223 char *ret;
225 ret = FGets(config_file, line, 512);
227 if (ret == NULL)
229 FreeVec(line);
230 break;
233 if (ret[0] == '0' &&
234 ret[1] == 'x' &&
235 ret[6] == ',' &&
236 ret[7] == ' ' &&
237 ret[8] == '0' &&
238 ret[9] == 'x' &&
239 ret[15] == '\0')
241 int value;
242 UWORD vendor, device;
243 char *tmp = (char *) AllocVec(16, MEMF_CLEAR);
244 char *tmp2 = (char *) AllocVec(4, MEMF_CLEAR);
246 CopyMem(line + 2, tmp, 4);
247 tmp[4] = '\0';
249 // convert hex to decimal
250 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]);
251 vendor = (UWORD) value;
253 CopyMem(line + 10, tmp, 4);
254 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]);
255 device = (UWORD) value;
256 //bug("Adding vendor = %x, device = %x to list, size = %ld\n", vendor, device, vendor_device_list_size);
258 vendor_device_list[vendor_device_list_size].vendor = vendor;
259 vendor_device_list[vendor_device_list_size].device = device;
260 vendor_device_list_size++;
262 if (vendor_device_list_size >= MAX_DEVICE_VENDORS)
264 bug("Exceeded MAX_DEVICE_VENDORS\n");
265 break;
268 FreeVec(tmp);
269 FreeVec(tmp2);
271 else if (ret[0] == 'Q' && ret[1] == 'U' && ret[2] == 'E' && ret[3] == 'R' && ret[4] == 'Y')
273 bug("QUERY found!\n");
274 setForceQuery();
276 if (ret[5] == 'D') // debug
278 setDumpAll();
281 else if (Strnicmp(ret, "speaker=0x", 10) == 0)
283 int speaker = 0;
284 char *tmp = (char *) AllocVec(16, MEMF_CLEAR);
286 CopyMem(line + 10, tmp, 2);
287 tmp[2] = '\0';
289 // convert hex to decimal
290 speaker = hex_char_to_int(tmp[0]) * 16 + hex_char_to_int(tmp[1]);
292 bug("Speaker in config = %x!\n", speaker);
294 setForceSpeaker(speaker);
297 FreeVec(line);
300 Close(config_file);
302 else
304 bug("Couldn't open config file!\n");
309 static int hex_char_to_int(char c)
311 if (c >= '0' && c <= '9')
313 return (c - '0');
315 else if (c >= 'A' && c <= 'F')
317 return 10 + (c - 'A');
319 else if (c >= 'a' && c <= 'f')
321 return 10 + (c - 'a');
323 else
325 bug("Error in hex_char_to_int: char was %c\n", c);
326 return 0;