Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / devs / AHI / Drivers / ac97 / ac97-init.c
blobeeba81e5ec3fc65b509b1d2185a384e121211243
1 #define DEBUG 0
2 #include <aros/debug.h>
3 #include <asm/io.h>
5 #include "library.h"
6 #include "DriverData.h"
8 OOP_AttrBase __IHidd_PCIDev;
10 static const struct {
11 UWORD VendorID;
12 UWORD ProductID;
13 STRPTR Model;
14 } support[] = {
15 { 0x8086, 0x2415, "Intel 82801AA" },
16 { 0x8086, 0x2425, "Intel 82801AB" },
17 { 0x8086, 0x2445, "Intel 82801BA" },
18 { 0x8086, 0x2485, "Intel ICH3" },
19 { 0x8086, 0x24c5, "Intel ICH4" },
20 { 0x8086, 0x24d5, "Intel ICH5" },
21 { 0x8086, 0x25a6, "ESB" },
22 { 0x8086, 0x266e, "Intel ICH6" },
23 { 0x8086, 0x27de, "Intel ICH7" },
24 { 0x8086, 0x2698, "ESB2" },
25 { 0x8086, 0x7195, "Intel 440MX" },
26 { 0x1039, 0x7012, "SIS 7012" },
27 { 0x10de, 0x01b1, "NVIDIA nForce" },
28 { 0x10de, 0x003a, "MCP04" },
29 { 0x10de, 0x006a, "NVIDIA nForce2" },
30 { 0x10de, 0x0059, "CK804" },
31 { 0x10de, 0x008a, "MCP2S AC'97 Audio Controller" },
32 { 0x10de, 0x00da, "NVIDIA nForce3" },
33 { 0x10de, 0x00ea, "CK8S" },
34 { 0x10de, 0x026b, "MCP51" },
35 { 0x1022, 0x746d, "AMD 8111" },
36 { 0x1022, 0x7445, "AMD 768" },
37 { 0x10b9, 0x5455, "Ali 5455" },
38 {0,0,NULL},
41 static void i8x0_set_reg(struct ac97Base *ac97Base, ULONG reg, UWORD value)
43 int count=1000000;
45 while(count-- && (inb(ac97Base->dmabase + ACC_SEMA) & 1));
47 outw(value, reg+ac97Base->mixerbase);
50 static UWORD i8x0_get_reg(struct ac97Base *ac97Base, ULONG reg)
52 int count=1000000;
54 while(count-- && (inb(ac97Base->dmabase + ACC_SEMA) & 1));
56 return inw(reg+ac97Base->mixerbase);
59 /******************************************************************************
60 ** Custom driver init *********************************************************
61 ******************************************************************************/
62 #define ac97Base ((struct ac97Base *)hook->h_Data)
63 #define AHIsubBase ((struct DriverBase *)hook->h_Data)
64 static AROS_UFH3(void, Enumerator,
65 AROS_UFHA(struct Hook *, hook, A0),
66 AROS_UFHA(OOP_Object *, device, A2),
67 AROS_UFHA(APTR, msg, A1))
69 AROS_USERFUNC_INIT
71 IPTR VendorID, ProductID, value;
72 int i;
74 OOP_GetAttr(device, aHidd_PCIDevice_ProductID, &ProductID);
75 OOP_GetAttr(device, aHidd_PCIDevice_VendorID, &VendorID);
77 D(bug("[ac97] Found audio device %04x:%04x\n", VendorID, ProductID));
79 for (i=0; support[i].VendorID; i++)
81 if (VendorID == support[i].VendorID && ProductID == support[i].ProductID)
83 struct TagItem attrs[] = {
84 { aHidd_PCIDevice_isIO, TRUE },
85 { aHidd_PCIDevice_isMEM, FALSE },
86 { aHidd_PCIDevice_isMaster, TRUE },
87 { TAG_DONE, 0UL },
90 D(bug("[ac97] Found supported '%s' card\n", support[i].Model));
91 ac97Base->cardfound = TRUE;
92 ac97Base->mixer_set_reg = i8x0_set_reg;
93 ac97Base->mixer_get_reg = i8x0_get_reg;
95 OOP_SetAttrs(device, (struct TagItem *)&attrs);
97 OOP_GetAttr(device, aHidd_PCIDevice_Base0, &value);
98 ac97Base->mixerbase = (ULONG)value;
99 OOP_GetAttr(device, aHidd_PCIDevice_Base1, &value);
100 ac97Base->dmabase = (ULONG)value;
101 OOP_GetAttr(device, aHidd_PCIDevice_INTLine, &value);
102 ac97Base->irq_num = (ULONG)value;
104 D(bug("[ac97] Mixer IO base %x\n", ac97Base->mixerbase));
105 D(bug("[ac97] DMA IO base %x\n", ac97Base->dmabase));
107 if (VendorID == 0x1039 && ProductID == 0x7012)
109 /* SIS 7012 */
110 ac97Base->off_po_sr = DEFAULT_PO_PICB; /* swap registers */
111 ac97Base->off_po_picb = DEFAULT_PO_SR;
112 ac97Base->size_shift = 1; /* chip requires size in bytes, not samples */
114 else
116 /* All other cards */
117 ac97Base->off_po_sr = DEFAULT_PO_SR; /* swap registers */
118 ac97Base->off_po_picb = DEFAULT_PO_PICB;
119 ac97Base->size_shift = 0;
122 outl(2, ac97Base->dmabase + GLOB_CNT);
124 ac97Base->mixer_set_reg(ac97Base, AC97_RESET, 0);
125 ac97Base->mixer_set_reg(ac97Base, AC97_POWERDOWN, 0);
127 /* Set master volume to no attenuation, mute off */
128 ac97Base->mixer_set_reg(ac97Base, AC97_MASTER_VOL, 0x0000);
129 ac97Base->mixer_set_reg(ac97Base, AC97_HEADPHONE_VOL, 0x0000);
130 ac97Base->mixer_set_reg(ac97Base, AC97_TONE, 0x0f0f);
131 ac97Base->mixer_set_reg(ac97Base, AC97_PCM_VOL, 0x0000);
133 D(bug("[ac97] Powerdown = %02x\n", ac97Base->mixer_get_reg(ac97Base, AC97_POWERDOWN)));
134 D(bug("[ac97] GLOB_CNT = %08x\n", inl(ac97Base->dmabase + GLOB_CNT)));
135 D(bug("[ac97] GLOB_STA = %08x\n", inl(ac97Base->dmabase + GLOB_STA)));
138 int i;
139 for (i=0; i < 64; i+=2)
141 D(bug("[ac97] reg %02x = %04x\n", i, ac97Base->mixer_get_reg(ac97Base, i)));
144 outl((ULONG)ac97Base->PCM_out, ac97Base->dmabase + PO_BDBAR);
146 D(bug("[ac97] PO_BDBAR=%08x\n", inl(ac97Base->dmabase + PO_BDBAR)));
147 D(bug("[ac97] PO_REGS=%08x\n", inl(ac97Base->dmabase + PO_CIV)));
148 D(bug("[ac97] PO_PICB=%04x\n", inw(ac97Base->dmabase + ac97Base->off_po_picb)));
149 D(bug("[ac97] PO_PIV=%02x\n", inb(ac97Base->dmabase + PO_PIV)));
150 D(bug("[ac97] PO_CR=%02x\n", inb(ac97Base->dmabase + PO_CR)));
154 AROS_USERFUNC_EXIT
156 #undef ac97Base
157 #undef AHIsubBase
159 BOOL DriverInit( struct DriverBase* AHIsubBase )
161 struct ac97Base* ac97Base = (struct ac97Base*) AHIsubBase;
163 ac97Base->dosbase = OpenLibrary( DOSNAME, 37 );
164 ac97Base->sysbase = SysBase;
166 D(bug("[ac97] Init\n"));
168 if(DOSBase)
170 ac97Base->oopbase = (APTR)OpenLibrary(AROSOOP_NAME, 0);
171 if (OOPBase)
173 __IHidd_PCIDev = OOP_ObtainAttrBase(IID_Hidd_PCIDevice);
175 D(bug("[ac97] Libraries opened\n"));
177 if (__IHidd_PCIDev)
179 OOP_Object *pci = OOP_NewObject(NULL, CLID_Hidd_PCI, NULL);
181 D(bug("[ac97] PCIDevice AttrBase = %x\n",__IHidd_PCIDev));
183 if (pci)
185 struct Hook FindHook = {
186 h_Entry: (IPTR(*)())Enumerator,
187 h_Data: ac97Base,
190 struct TagItem Reqs[] = {
191 { tHidd_PCI_Class, 0x04 },
192 { tHidd_PCI_SubClass, 0x01 },
193 { TAG_DONE, 0UL },
196 struct pHidd_PCI_EnumDevices enummsg = {
197 mID: OOP_GetMethodID(CLID_Hidd_PCI, moHidd_PCI_EnumDevices),
198 callback: &FindHook,
199 requirements: (struct TagItem *)&Reqs,
200 }, *msg = &enummsg;
202 D(bug("[ac97] Got PCI object\n"));
204 ac97Base->cardfound = FALSE;
205 ac97Base->PCM_out = AllocMem(8*32, MEMF_PUBLIC | MEMF_CLEAR);
207 OOP_DoMethod(pci, (OOP_Msg)msg);
209 OOP_DisposeObject(pci);
211 D(bug("[ac97] PCM out base %08x\n", ac97Base->PCM_out));
213 return ac97Base->cardfound;
217 else
219 Req("Unable to open 'oop.library'\n");
222 else
224 Req( "Unable to open 'dos.library' version 37.\n" );
227 return FALSE;
231 /******************************************************************************
232 ** Custom driver clean-up *****************************************************
233 ******************************************************************************/
235 VOID DriverCleanup( struct DriverBase* AHIsubBase )
237 struct ac97Base* ac97Base = (struct ac97Base*) AHIsubBase;
239 OOP_ReleaseAttrBase(IID_Hidd_PCIDevice);
240 CloseLibrary( (struct Library*) DOSBase );
241 CloseLibrary( (struct Library*) ac97Base->oopbase);