2 #include <exec/memory.h>
4 #include <proto/expansion.h>
6 #include <proto/exec.h>
7 #include <clib/alib_protos.h>
9 #include <aros/debug.h>
10 struct ExecBase
* SysBase
= NULL
;
11 struct DosLibrary
* DOSBase
;
17 #include "pci_wrapper.h"
22 struct DriverBase
* AHIsubBase
;
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
;
51 bug("ENTERING HDAUDIO!\n");
52 AHIsubBase
= ahisubbase
;
54 DOSBase
= (struct DosLibrary
*) OpenLibrary(DOSNAME
, 37);
58 Req("Unable to open 'dos.library' version 37.\n");
62 if (!ahi_pci_init(ahisubbase
))
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:
81 bug("vendor_device_list_size = %ld\n", vendor_device_list_size
);
83 card_base
->cards_found
= 0;
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
);
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");
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");
125 card_base
->driverdatas
[card_no
] = AllocDriverData(dev
, AHIsubBase
);
126 if (card_base
->driverdatas
[card_no
] == NULL
)
139 /******************************************************************************
140 ** Custom driver clean-up *****************************************************
141 ******************************************************************************/
143 VOID
DriverCleanup(struct DriverBase
* AHIsubBase
)
145 struct HDAudioBase
* card_base
= (struct HDAudioBase
*) AHIsubBase
;
148 for(i
= 0; i
< card_base
->cards_found
; ++i
)
150 FreeDriverData(card_base
->driverdatas
[i
], AHIsubBase
);
153 FreeVec(card_base
->driverdatas
);
159 CloseLibrary((struct Library
*) DOSBase
);
164 static void parse_config_file()
169 handle
= Lock("ENV:hdaudio.config", SHARED_LOCK
);
173 bug("No handle found\n");
179 config_file
= Open("ENV:hdaudio.config", MODE_OLDFILE
);
183 BOOL Continue
= TRUE
;
184 bug("Opened config file\n");
188 char *line
= (char *) AllocVec(512, MEMF_CLEAR
);
191 ret
= FGets(config_file
, line
, 512);
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);
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");
237 else if (ret
[0] == 'Q' && ret
[1] == 'U' && ret
[2] == 'E' && ret
[3] == 'R' && ret
[4] == 'Y')
239 bug("QUERY found!\n");
242 if (ret
[5] == 'D') // debug
247 else if (Strnicmp(ret
, "speaker=0x", 10) == 0)
250 char *tmp
= (char *) AllocVec(16, MEMF_CLEAR
);
252 CopyMem(line
+ 10, tmp
, 2);
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
);
270 bug("Couldn't open config file!\n");
275 static int hex_char_to_int(char c
)
277 if (c
>= '0' && c
<= '9')
281 else if (c
>= 'A' && c
<= 'F')
283 return 10 + (c
- 'A');
285 else if (c
>= 'a' && c
<= 'f')
287 return 10 + (c
- 'a');
291 bug("Error in hex_char_to_int: char was %c\n", c
);