2 #include <aros/debug.h>
10 #include "DriverData.h"
12 OOP_AttrBase __IHidd_PCIDev
;
19 { 0x8086, 0x2415, "Intel 82801AA" },
20 { 0x8086, 0x2425, "Intel 82801AB" },
21 { 0x8086, 0x2445, "Intel 82801BA" },
22 { 0x8086, 0x2485, "Intel ICH3" },
23 { 0x8086, 0x24c5, "Intel ICH4" },
24 { 0x8086, 0x24d5, "Intel ICH5" },
25 { 0x8086, 0x25a6, "ESB" },
26 { 0x8086, 0x266e, "Intel ICH6" },
27 { 0x8086, 0x27de, "Intel ICH7" },
28 { 0x8086, 0x2698, "ESB2" },
29 { 0x8086, 0x7195, "Intel 440MX" },
30 { 0x1039, 0x7012, "SIS 7012" },
31 { 0x10de, 0x01b1, "NVIDIA nForce" },
32 { 0x10de, 0x003a, "MCP04" },
33 { 0x10de, 0x006a, "NVIDIA nForce2" },
34 { 0x10de, 0x0059, "CK804" },
35 { 0x10de, 0x008a, "MCP2S AC'97 Audio Controller" },
36 { 0x10de, 0x00da, "NVIDIA nForce3" },
37 { 0x10de, 0x00ea, "CK8S" },
38 { 0x10de, 0x026b, "MCP51" },
39 { 0x1022, 0x746d, "AMD 8111" },
40 { 0x1022, 0x7445, "AMD 768" },
41 { 0x10b9, 0x5455, "Ali 5455" },
45 static void i8x0_set_reg(struct ac97Base
*ac97Base
, ULONG reg
, UWORD value
)
49 while(count
-- && (inb(ac97Base
->dmabase
+ ACC_SEMA
) & 1));
51 outw(value
, reg
+ac97Base
->mixerbase
);
54 static UWORD
i8x0_get_reg(struct ac97Base
*ac97Base
, ULONG reg
)
58 while(count
-- && (inb(ac97Base
->dmabase
+ ACC_SEMA
) & 1));
60 return inw(reg
+ac97Base
->mixerbase
);
63 /******************************************************************************
64 ** Custom driver init *********************************************************
65 ******************************************************************************/
66 #define ac97Base ((struct ac97Base *)hook->h_Data)
67 #define AHIsubBase ((struct DriverBase *)hook->h_Data)
68 static AROS_UFH3(void, Enumerator
,
69 AROS_UFHA(struct Hook
*, hook
, A0
),
70 AROS_UFHA(OOP_Object
*, device
, A2
),
71 AROS_UFHA(APTR
, msg
, A1
))
75 ULONG VendorID
,ProductID
;
78 OOP_GetAttr(device
, aHidd_PCIDevice_ProductID
, &ProductID
);
79 OOP_GetAttr(device
, aHidd_PCIDevice_VendorID
, &VendorID
);
81 D(bug("[ac97] Found audio device %04x:%04x\n", 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
},
94 D(bug("[ac97] Found supported '%s' card\n", support
[i
].Model
));
95 ac97Base
->cardfound
= TRUE
;
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
, &ac97Base
->mixerbase
);
102 OOP_GetAttr(device
, aHidd_PCIDevice_Base1
, &ac97Base
->dmabase
);
103 OOP_GetAttr(device
, aHidd_PCIDevice_INTLine
, &ac97Base
->irq_num
);
105 D(bug("[ac97] Mixer IO base %x\n", ac97Base
->mixerbase
));
106 D(bug("[ac97] DMA IO base %x\n", ac97Base
->dmabase
));
108 if (VendorID
== 0x1039 && ProductID
== 0x7012)
111 ac97Base
->off_po_sr
= DEFAULT_PO_PICB
; /* swap registers */
112 ac97Base
->off_po_picb
= DEFAULT_PO_SR
;
113 ac97Base
->size_shift
= 1; /* chip requires size in bytes, not samples */
117 /* All other cards */
118 ac97Base
->off_po_sr
= DEFAULT_PO_SR
; /* swap registers */
119 ac97Base
->off_po_picb
= DEFAULT_PO_PICB
;
120 ac97Base
->size_shift
= 0;
123 outl(2, ac97Base
->dmabase
+ GLOB_CNT
);
125 ac97Base
->mixer_set_reg(ac97Base
, AC97_RESET
, 0);
126 ac97Base
->mixer_set_reg(ac97Base
, AC97_POWERDOWN
, 0);
128 /* Set master volume to no attenuation, mute off */
129 ac97Base
->mixer_set_reg(ac97Base
, AC97_MASTER_VOL
, 0x0000);
130 ac97Base
->mixer_set_reg(ac97Base
, AC97_HEADPHONE_VOL
, 0x0000);
131 ac97Base
->mixer_set_reg(ac97Base
, AC97_TONE
, 0x0f0f);
132 ac97Base
->mixer_set_reg(ac97Base
, AC97_PCM_VOL
, 0x0000);
134 D(bug("[ac97] Powerdown = %02x\n", ac97Base
->mixer_get_reg(ac97Base
, AC97_POWERDOWN
)));
135 D(bug("[ac97] GLOB_CNT = %08x\n", inl(ac97Base
->dmabase
+ GLOB_CNT
)));
136 D(bug("[ac97] GLOB_STA = %08x\n", inl(ac97Base
->dmabase
+ GLOB_STA
)));
140 for (i=0; i < 64; i+=2)
142 D(bug("[ac97] reg %02x = %04x\n", i, ac97Base->mixer_get_reg(ac97Base, i)));
145 outl(ac97Base
->PCM_out
, ac97Base
->dmabase
+ PO_BDBAR
);
147 D(bug("[ac97] PO_BDBAR=%08x\n", inl(ac97Base
->dmabase
+ PO_BDBAR
)));
148 D(bug("[ac97] PO_REGS=%08x\n", inl(ac97Base
->dmabase
+ PO_CIV
)));
149 D(bug("[ac97] PO_PICB=%04x\n", inw(ac97Base
->dmabase
+ ac97Base
->off_po_picb
)));
150 D(bug("[ac97] PO_PIV=%02x\n", inb(ac97Base
->dmabase
+ PO_PIV
)));
151 D(bug("[ac97] PO_CR=%02x\n", inb(ac97Base
->dmabase
+ PO_CR
)));
160 BOOL
DriverInit( struct DriverBase
* AHIsubBase
)
162 struct ac97Base
* ac97Base
= (struct ac97Base
*) AHIsubBase
;
164 ac97Base
->dosbase
= OpenLibrary( DOSNAME
, 37 );
165 ac97Base
->sysbase
= SysBase
;
167 D(bug("[ac97] Init\n"));
171 ac97Base
->oopbase
= OpenLibrary(AROSOOP_NAME
, 0);
174 __IHidd_PCIDev
= OOP_ObtainAttrBase(IID_Hidd_PCIDevice
);
176 D(bug("[ac97] Libraries opened\n"));
180 OOP_Object
*pci
= OOP_NewObject(NULL
, CLID_Hidd_PCI
, NULL
);
182 D(bug("[ac97] PCIDevice AttrBase = %x\n",__IHidd_PCIDev
));
186 struct Hook FindHook
= {
187 h_Entry
: (IPTR(*)())Enumerator
,
191 struct TagItem Reqs
[] = {
192 { tHidd_PCI_Class
, 0x04 },
193 { tHidd_PCI_SubClass
, 0x01 },
197 struct pHidd_PCI_EnumDevices enummsg
= {
198 mID
: OOP_GetMethodID(CLID_Hidd_PCI
, moHidd_PCI_EnumDevices
),
200 requirements
: (struct TagItem
*)&Reqs
,
203 D(bug("[ac97] Got PCI object\n"));
205 ac97Base
->cardfound
= FALSE
;
206 ac97Base
->PCM_out
= AllocMem(8*32, MEMF_PUBLIC
| MEMF_CLEAR
);
208 OOP_DoMethod(pci
, (OOP_Msg
)msg
);
210 OOP_DisposeObject(pci
);
212 D(bug("[ac97] PCM out base %08x\n", ac97Base
->PCM_out
));
214 return ac97Base
->cardfound
;
220 Req("Unable to open 'oop.library'\n");
225 Req( "Unable to open 'dos.library' version 37.\n" );
232 /******************************************************************************
233 ** Custom driver clean-up *****************************************************
234 ******************************************************************************/
236 VOID
DriverCleanup( struct DriverBase
* AHIsubBase
)
238 struct ac97Base
* ac97Base
= (struct ac97Base
*) AHIsubBase
;
240 OOP_ReleaseAttrBase(IID_Hidd_PCIDevice
);
241 CloseLibrary( (struct Library
*) DOSBase
);
242 CloseLibrary( (struct Library
*) ac97Base
->oopbase
);