debug cleanup and 64bit corrections.
[AROS.git] / workbench / devs / AHI / Drivers / ac97 / ac97-init.c
blob26d4d027e89ceb144bc7a48bb6af3b3b553280cc
2 #define DEBUG 1
3 #include <aros/debug.h>
5 #include <asm/io.h>
7 #include "library.h"
8 #include "DriverData.h"
10 OOP_AttrBase __IHidd_PCIDev;
12 static const struct {
13 UWORD VendorID;
14 UWORD ProductID;
15 STRPTR Model;
16 } support[] = {
17 { 0x8086, 0x2415, "Intel 82801AA" },
18 { 0x8086, 0x2425, "Intel 82801AB" },
19 { 0x8086, 0x2445, "Intel 82801BA" },
20 { 0x8086, 0x2485, "Intel ICH3" },
21 { 0x8086, 0x24c5, "Intel ICH4" },
22 { 0x8086, 0x24d5, "Intel ICH5" },
23 { 0x8086, 0x25a6, "ESB" },
24 { 0x8086, 0x266e, "Intel ICH6" },
25 { 0x8086, 0x27de, "Intel ICH7" },
26 { 0x8086, 0x2698, "ESB2" },
27 { 0x8086, 0x7195, "Intel 440MX" },
28 { 0x1039, 0x7012, "SIS 7012" },
29 { 0x10de, 0x01b1, "NVIDIA nForce" },
30 { 0x10de, 0x003a, "MCP04" },
31 { 0x10de, 0x006a, "NVIDIA nForce2" },
32 { 0x10de, 0x0059, "CK804" },
33 { 0x10de, 0x008a, "MCP2S AC'97 Audio Controller" },
34 { 0x10de, 0x00da, "NVIDIA nForce3" },
35 { 0x10de, 0x00ea, "CK8S" },
36 { 0x10de, 0x026b, "MCP51" },
37 { 0x1022, 0x746d, "AMD 8111" },
38 { 0x1022, 0x7445, "AMD 768" },
39 { 0x10b9, 0x5455, "Ali 5455" },
40 {0,0,NULL},
43 static void i8x0_set_reg(struct ac97Base *ac97Base, ULONG reg, UWORD value)
45 int count=1000000;
47 while(count-- && (inb((IPTR)ac97Base->dmabase + ACC_SEMA) & 1));
49 outw(value, (IPTR)ac97Base->mixerbase + reg);
52 static UWORD i8x0_get_reg(struct ac97Base *ac97Base, ULONG reg)
54 int count=1000000;
56 while(count-- && (inb((IPTR)ac97Base->dmabase + ACC_SEMA) & 1));
58 return inw((IPTR)ac97Base->mixerbase + reg);
61 /******************************************************************************
62 ** Custom driver init *********************************************************
63 ******************************************************************************/
64 #define ac97Base ((struct ac97Base *)hook->h_Data)
65 #define AHIsubBase ((struct DriverBase *)hook->h_Data)
66 static AROS_UFH3(void, Enumerator,
67 AROS_UFHA(struct Hook *, hook, A0),
68 AROS_UFHA(OOP_Object *, device, A2),
69 AROS_UFHA(APTR, msg, A1))
71 AROS_USERFUNC_INIT
73 IPTR VendorID = 0, ProductID = 0, value = 0;
74 int i;
76 D(bug("[AHI:AC97] %s()\n", __func__));
78 OOP_GetAttr(device, aHidd_PCIDevice_ProductID, &ProductID);
79 OOP_GetAttr(device, aHidd_PCIDevice_VendorID, &VendorID);
81 D(bug("[AHI:AC97] %s: Querying PCI 'audio' device %04x:%04x\n", __func__, VendorID, ProductID));
83 for (i=0; support[i].VendorID; i++)
85 if (VendorID == support[i].VendorID && ProductID == support[i].ProductID)
87 struct TagItem attrs[] = {
88 { aHidd_PCIDevice_isIO, TRUE },
89 { aHidd_PCIDevice_isMEM, FALSE },
90 { aHidd_PCIDevice_isMaster, TRUE },
91 { TAG_DONE, 0UL },
94 D(bug("[AHI:AC97] %s: Detected supported '%s' card\n", __func__, support[i].Model));
96 ac97Base->mixer_set_reg = i8x0_set_reg;
97 ac97Base->mixer_get_reg = i8x0_get_reg;
99 OOP_SetAttrs(device, (struct TagItem *)&attrs);
101 OOP_GetAttr(device, aHidd_PCIDevice_Base0, &value);
102 ac97Base->mixerbase = (APTR)value;
103 OOP_GetAttr(device, aHidd_PCIDevice_Base1, &value);
104 ac97Base->dmabase = (APTR)value;
105 OOP_GetAttr(device, aHidd_PCIDevice_INTLine, &value);
106 ac97Base->irq_num = (ULONG)value;
109 bug("[AHI:AC97] %s: Mixer IO base @ %p\n", __func__, ac97Base->mixerbase);
110 bug("[AHI:AC97] %s: DMA IO base @ %p\n", __func__, ac97Base->dmabase);
113 if (VendorID == 0x1039 && ProductID == 0x7012)
115 /* SIS 7012 */
116 ac97Base->off_po_sr = DEFAULT_PO_PICB; /* swap registers */
117 ac97Base->off_po_picb = DEFAULT_PO_SR;
118 ac97Base->size_shift = 1; /* chip requires size in bytes, not samples */
120 else
122 /* All other cards */
123 ac97Base->off_po_sr = DEFAULT_PO_SR; /* swap registers */
124 ac97Base->off_po_picb = DEFAULT_PO_PICB;
125 ac97Base->size_shift = 0;
128 if ((value = (IPTR)AllocMem((8*32) + ALIGN_AC97OUT, MEMF_PUBLIC | MEMF_31BIT | MEMF_CLEAR)) != 0)
130 ac97Base->PCM_out = (APTR)ALIGN_AC97(value);
131 D(bug("[AHI:AC97] %s: PCM_out base @ %p\n", __func__, ac97Base->PCM_out));
133 ac97Base->cardfound = TRUE;
135 outl(2, (IPTR)ac97Base->dmabase + GLOB_CNT);
137 ac97Base->mixer_set_reg(ac97Base, AC97_RESET, 0);
138 ac97Base->mixer_set_reg(ac97Base, AC97_POWERDOWN, 0);
140 /* Set master volume to no attenuation, mute off */
141 ac97Base->mixer_set_reg(ac97Base, AC97_MASTER_VOL, 0x0000);
142 ac97Base->mixer_set_reg(ac97Base, AC97_HEADPHONE_VOL, 0x0000);
143 ac97Base->mixer_set_reg(ac97Base, AC97_TONE, 0x0f0f);
144 ac97Base->mixer_set_reg(ac97Base, AC97_PCM_VOL, 0x0000);
147 bug("[AHI:AC97] %s: Powerdown = %02x\n", __func__, ac97Base->mixer_get_reg(ac97Base, AC97_POWERDOWN));
148 bug("[AHI:AC97] %s: GLOB_CNT = %08x\n", __func__, inl((IPTR)ac97Base->dmabase + GLOB_CNT));
149 bug("[AHI:AC97] %s: GLOB_STA = %08x\n", __func__, inl((IPTR)ac97Base->dmabase + GLOB_STA));
153 int i;
154 for (i=0; i < 64; i+=2)
156 D(bug("[AHI:AC97] reg %02x = %04x\n", i, ac97Base->mixer_get_reg(ac97Base, i)));
159 outl((ULONG)(IPTR)ac97Base->PCM_out, (IPTR)ac97Base->dmabase + PO_BDBAR);
162 bug("[AHI:AC97] %s: PO_BDBAR=%p\n", __func__, (APTR)(IPTR)inl((IPTR)ac97Base->dmabase + PO_BDBAR));
163 bug("[AHI:AC97] %s: PO_REGS=%08x\n", __func__, inl((IPTR)ac97Base->dmabase + PO_CIV));
164 bug("[AHI:AC97] %s: PO_PICB=%04x\n", __func__, inw((IPTR)ac97Base->dmabase + ac97Base->off_po_picb));
165 bug("[AHI:AC97] %s: PO_PIV=%02x\n", __func__, inb((IPTR)ac97Base->dmabase + PO_PIV));
166 bug("[AHI:AC97] %s: PO_CR=%02x\n", __func__, inb((IPTR)ac97Base->dmabase + PO_CR));
172 AROS_USERFUNC_EXIT
174 #undef ac97Base
175 #undef AHIsubBase
177 BOOL DriverInit( struct DriverBase* AHIsubBase )
179 struct ac97Base* ac97Base = (struct ac97Base*) AHIsubBase;
181 ac97Base->dosbase = OpenLibrary( DOSNAME, 37 );
182 ac97Base->sysbase = SysBase;
184 D(bug("[AHI:AC97] %s()\n", __func__));
186 if(DOSBase)
188 ac97Base->oopbase = (APTR)OpenLibrary(AROSOOP_NAME, 0);
189 if (OOPBase)
191 __IHidd_PCIDev = OOP_ObtainAttrBase(IID_Hidd_PCIDevice);
193 D(bug("[AHI:AC97] %s: Libraries opened\n", __func__));
195 if (__IHidd_PCIDev)
197 OOP_Object *pci = OOP_NewObject(NULL, CLID_Hidd_PCI, NULL);
199 D(bug("[AHI:AC97] %s: PCIDevice AttrBase = %x\n", __func__, __IHidd_PCIDev));
201 if (pci)
203 struct Hook FindHook = {
204 h_Entry: (IPTR(*)())Enumerator,
205 h_Data: ac97Base,
208 struct TagItem Reqs[] = {
209 { tHidd_PCI_Class, 0x04 },
210 { tHidd_PCI_SubClass, 0x01 },
211 { TAG_DONE, 0UL },
214 struct pHidd_PCI_EnumDevices enummsg = {
215 mID: OOP_GetMethodID(CLID_Hidd_PCI, moHidd_PCI_EnumDevices),
216 callback: &FindHook,
217 requirements: (struct TagItem *)&Reqs,
218 }, *msg = &enummsg;
220 D(bug("[AHI:AC97] %s: Got PCI object\n", __func__));
222 ac97Base->cardfound = FALSE;
224 OOP_DoMethod(pci, (OOP_Msg)msg);
226 OOP_DisposeObject(pci);
228 return ac97Base->cardfound;
232 else
234 Req("Unable to open 'oop.library'\n");
237 else
239 Req( "Unable to open 'dos.library' version 37.\n" );
242 return FALSE;
246 /******************************************************************************
247 ** Custom driver clean-up *****************************************************
248 ******************************************************************************/
250 VOID DriverCleanup( struct DriverBase* AHIsubBase )
252 struct ac97Base* ac97Base = (struct ac97Base*) AHIsubBase;
254 OOP_ReleaseAttrBase(IID_Hidd_PCIDevice);
255 CloseLibrary( (struct Library*) DOSBase );
256 CloseLibrary( (struct Library*) ac97Base->oopbase);