3 #include <aros/debug.h>
8 #include "DriverData.h"
10 OOP_AttrBase __IHidd_PCIDev
;
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" },
43 static void i8x0_set_reg(struct ac97Base
*ac97Base
, ULONG reg
, UWORD value
)
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
)
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
))
73 IPTR VendorID
= 0, ProductID
= 0, value
= 0;
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
},
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)
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 */
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 defined(__AROS__) && (__WORDSIZE==64)
129 ac97Base
->buffer
= CreatePool(MEMF_CLEAR
| MEMF_31BIT
, 131072, 65536);
131 if ((value
= (IPTR
)AllocMem((8*32) + ALIGN_AC97OUT
, MEMF_PUBLIC
| MEMF_31BIT
| MEMF_CLEAR
)) != 0)
133 ac97Base
->PCM_out
= (APTR
)ALIGN_AC97(value
);
134 D(bug("[AHI:AC97] %s: PCM_out base @ %p\n", __func__
, ac97Base
->PCM_out
));
136 ac97Base
->cardfound
= TRUE
;
138 outl(2, (IPTR
)ac97Base
->dmabase
+ GLOB_CNT
);
140 ac97Base
->mixer_set_reg(ac97Base
, AC97_RESET
, 0);
141 ac97Base
->mixer_set_reg(ac97Base
, AC97_POWERDOWN
, 0);
143 /* Set master volume to no attenuation, mute off */
144 ac97Base
->mixer_set_reg(ac97Base
, AC97_MASTER_VOL
, 0x0000);
145 ac97Base
->mixer_set_reg(ac97Base
, AC97_HEADPHONE_VOL
, 0x0000);
146 ac97Base
->mixer_set_reg(ac97Base
, AC97_TONE
, 0x0f0f);
147 ac97Base
->mixer_set_reg(ac97Base
, AC97_PCM_VOL
, 0x0000);
150 bug("[AHI:AC97] %s: Powerdown = %02x\n", __func__
, ac97Base
->mixer_get_reg(ac97Base
, AC97_POWERDOWN
));
151 bug("[AHI:AC97] %s: GLOB_CNT = %08x\n", __func__
, inl((IPTR
)ac97Base
->dmabase
+ GLOB_CNT
));
152 bug("[AHI:AC97] %s: GLOB_STA = %08x\n", __func__
, inl((IPTR
)ac97Base
->dmabase
+ GLOB_STA
));
157 for (i=0; i < 64; i+=2)
159 D(bug("[AHI:AC97] reg %02x = %04x\n", i, ac97Base->mixer_get_reg(ac97Base, i)));
162 outl((ULONG
)(IPTR
)ac97Base
->PCM_out
, (IPTR
)ac97Base
->dmabase
+ PO_BDBAR
);
165 bug("[AHI:AC97] %s: PO_BDBAR=%p\n", __func__
, (APTR
)(IPTR
)inl((IPTR
)ac97Base
->dmabase
+ PO_BDBAR
));
166 bug("[AHI:AC97] %s: PO_REGS=%08x\n", __func__
, inl((IPTR
)ac97Base
->dmabase
+ PO_CIV
));
167 bug("[AHI:AC97] %s: PO_PICB=%04x\n", __func__
, inw((IPTR
)ac97Base
->dmabase
+ ac97Base
->off_po_picb
));
168 bug("[AHI:AC97] %s: PO_PIV=%02x\n", __func__
, inb((IPTR
)ac97Base
->dmabase
+ PO_PIV
));
169 bug("[AHI:AC97] %s: PO_CR=%02x\n", __func__
, inb((IPTR
)ac97Base
->dmabase
+ PO_CR
));
180 BOOL
DriverInit( struct DriverBase
* AHIsubBase
)
182 struct ac97Base
* ac97Base
= (struct ac97Base
*) AHIsubBase
;
184 ac97Base
->dosbase
= OpenLibrary( DOSNAME
, 37 );
185 ac97Base
->sysbase
= SysBase
;
187 D(bug("[AHI:AC97] %s()\n", __func__
));
191 ac97Base
->oopbase
= (APTR
)OpenLibrary(AROSOOP_NAME
, 0);
194 __IHidd_PCIDev
= OOP_ObtainAttrBase(IID_Hidd_PCIDevice
);
196 D(bug("[AHI:AC97] %s: Libraries opened\n", __func__
));
200 OOP_Object
*pci
= OOP_NewObject(NULL
, CLID_Hidd_PCI
, NULL
);
202 D(bug("[AHI:AC97] %s: PCIDevice AttrBase = %x\n", __func__
, __IHidd_PCIDev
));
206 struct Hook FindHook
= {
207 h_Entry
: (IPTR(*)())Enumerator
,
211 struct TagItem Reqs
[] = {
212 { tHidd_PCI_Class
, 0x04 },
213 { tHidd_PCI_SubClass
, 0x01 },
217 struct pHidd_PCI_EnumDevices enummsg
= {
218 mID
: OOP_GetMethodID(CLID_Hidd_PCI
, moHidd_PCI_EnumDevices
),
220 requirements
: (struct TagItem
*)&Reqs
,
223 D(bug("[AHI:AC97] %s: Got PCI object\n", __func__
));
225 ac97Base
->cardfound
= FALSE
;
227 OOP_DoMethod(pci
, (OOP_Msg
)msg
);
229 OOP_DisposeObject(pci
);
231 return ac97Base
->cardfound
;
237 Req("Unable to open 'oop.library'\n");
242 Req( "Unable to open 'dos.library' version 37.\n" );
249 /******************************************************************************
250 ** Custom driver clean-up *****************************************************
251 ******************************************************************************/
253 VOID
DriverCleanup( struct DriverBase
* AHIsubBase
)
255 struct ac97Base
* ac97Base
= (struct ac97Base
*) AHIsubBase
;
257 OOP_ReleaseAttrBase(IID_Hidd_PCIDevice
);
258 CloseLibrary( (struct Library
*) DOSBase
);
259 CloseLibrary( (struct Library
*) ac97Base
->oopbase
);