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 ((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
));
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
));
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__
));
188 ac97Base
->oopbase
= (APTR
)OpenLibrary(AROSOOP_NAME
, 0);
191 __IHidd_PCIDev
= OOP_ObtainAttrBase(IID_Hidd_PCIDevice
);
193 D(bug("[AHI:AC97] %s: Libraries opened\n", __func__
));
197 OOP_Object
*pci
= OOP_NewObject(NULL
, CLID_Hidd_PCI
, NULL
);
199 D(bug("[AHI:AC97] %s: PCIDevice AttrBase = %x\n", __func__
, __IHidd_PCIDev
));
203 struct Hook FindHook
= {
204 h_Entry
: (IPTR(*)())Enumerator
,
208 struct TagItem Reqs
[] = {
209 { tHidd_PCI_Class
, 0x04 },
210 { tHidd_PCI_SubClass
, 0x01 },
214 struct pHidd_PCI_EnumDevices enummsg
= {
215 mID
: OOP_GetMethodID(CLID_Hidd_PCI
, moHidd_PCI_EnumDevices
),
217 requirements
: (struct TagItem
*)&Reqs
,
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
;
234 Req("Unable to open 'oop.library'\n");
239 Req( "Unable to open 'dos.library' version 37.\n" );
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
);