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 DosLibrary
* DOSBase
;
16 #include "pci_wrapper.h"
21 struct DriverBase
* AHIsubBase
;
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
;
50 bug("ENTERING HDAUDIO!\n");
51 AHIsubBase
= ahisubbase
;
53 DOSBase
= (struct DosLibrary
*) OpenLibrary(DOSNAME
, 37);
57 Req("Unable to open 'dos.library' version 37.\n");
61 if (!ahi_pci_init(ahisubbase
))
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:
80 bug("vendor_device_list_size = %ld\n", vendor_device_list_size
);
82 card_base
->cards_found
= 0;
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
);
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");
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");
124 card_base
->driverdatas
[card_no
] = AllocDriverData(dev
, AHIsubBase
);
125 if (card_base
->driverdatas
[card_no
] == NULL
)
138 /******************************************************************************
139 ** Custom driver clean-up *****************************************************
140 ******************************************************************************/
142 VOID
DriverCleanup(struct DriverBase
* AHIsubBase
)
144 struct HDAudioBase
* card_base
= (struct HDAudioBase
*) AHIsubBase
;
147 for(i
= 0; i
< card_base
->cards_found
; ++i
)
149 FreeDriverData(card_base
->driverdatas
[i
], AHIsubBase
);
152 FreeVec(card_base
->driverdatas
);
158 CloseLibrary((struct Library
*) DOSBase
);
163 static void parse_config_file()
168 handle
= Lock("ENV:hdaudio.config", SHARED_LOCK
);
172 bug("No handle found\n");
178 config_file
= Open("ENV:hdaudio.config", MODE_OLDFILE
);
182 BOOL Continue
= TRUE
;
183 bug("Opened config file\n");
187 char *line
= (char *) AllocVec(512, MEMF_CLEAR
);
190 ret
= FGets(config_file
, line
, 512);
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);
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");
236 else if (ret
[0] == 'Q' && ret
[1] == 'U' && ret
[2] == 'E' && ret
[3] == 'R' && ret
[4] == 'Y')
238 bug("QUERY found!\n");
241 if (ret
[5] == 'D') // debug
246 else if (Strnicmp(ret
, "speaker=0x", 10) == 0)
249 char *tmp
= (char *) AllocVec(16, MEMF_CLEAR
);
251 CopyMem(line
+ 10, tmp
, 2);
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
);
269 bug("Couldn't open config file!\n");
274 static int hex_char_to_int(char c
)
276 if (c
>= '0' && c
<= '9')
280 else if (c
>= 'A' && c
<= 'F')
282 return 10 + (c
- 'A');
284 else if (c
>= 'a' && c
<= 'f')
286 return 10 + (c
- 'a');
290 bug("Error in hex_char_to_int: char was %c\n", c
);