1 #define __OOP_NOATTRBASES__
5 #include <utility/hooks.h>
6 #include <exec/interrupts.h>
11 #include <aros/asmcall.h>
13 #include <proto/oop.h>
15 #include "DriverData.h"
16 #include "pci_wrapper.h"
18 #include <aros/debug.h>
19 #define KPrintF kprintf
21 struct Library
*OOPBase
;
24 static OOP_AttrBase __IHidd_PCIDev
;
25 static OOP_Object
*pciobj
, *irqobj
;
27 static OOP_MethodID mid_RB
;
28 static OOP_MethodID mid_RW
;
29 static OOP_MethodID mid_RL
;
31 static OOP_MethodID mid_WB
;
32 static OOP_MethodID mid_WW
;
33 static OOP_MethodID mid_WL
;
35 static HIDDT_IRQ_Handler inthandler
;
36 static BOOL inthandler_added
;
38 BOOL
ahi_pci_init(struct DriverBase
* AHIsubBase
)
40 OOPBase
= OpenLibrary(AROSOOP_NAME
, 0);
43 __IHidd_PCIDev
= OOP_ObtainAttrBase(IID_Hidd_PCIDevice
);
46 pciobj
= OOP_NewObject(NULL
, CLID_Hidd_PCI
, NULL
);
47 irqobj
= OOP_NewObject(NULL
, CLID_Hidd_IRQ
, NULL
);
51 mid_RB
= OOP_GetMethodID(IID_Hidd_PCIDevice
, moHidd_PCIDevice_ReadConfigByte
);
52 mid_RW
= OOP_GetMethodID(IID_Hidd_PCIDevice
, moHidd_PCIDevice_ReadConfigWord
);
53 mid_RL
= OOP_GetMethodID(IID_Hidd_PCIDevice
, moHidd_PCIDevice_ReadConfigLong
);
55 mid_WB
= OOP_GetMethodID(IID_Hidd_PCIDevice
, moHidd_PCIDevice_WriteConfigByte
);
56 mid_WW
= OOP_GetMethodID(IID_Hidd_PCIDevice
, moHidd_PCIDevice_WriteConfigWord
);
57 mid_WL
= OOP_GetMethodID(IID_Hidd_PCIDevice
, moHidd_PCIDevice_WriteConfigLong
);
67 void ahi_pci_exit(void)
70 OOP_DisposeObject(irqobj
);
72 OOP_DisposeObject(pciobj
);
74 OOP_ReleaseAttrBase(IID_Hidd_PCIDevice
);
76 CloseLibrary(OOPBase
);
82 OOP_Object
*found_dev
;
85 static AROS_UFH3(void, Enumerator
,
86 AROS_UFHA(struct Hook
*, hook
, A0
),
87 AROS_UFHA(OOP_Object
*, device
, A2
),
88 AROS_UFHA(APTR
, msg
, A1
))
92 struct enum_data
*ed
= (struct enum_data
*)hook
->h_Data
;
94 if ((ed
->found_dev
== 0) && (device
!= ed
->prev_dev
))
96 ed
->found_dev
= device
;
103 APTR
ahi_pci_find_device(ULONG vendorid
, ULONG deviceid
, APTR dev
)
107 struct Hook FindHook
=
109 h_Entry
: (HOOKFUNC
)Enumerator
,
113 struct TagItem Reqs
[] =
116 { tHidd_PCI_Class
, 0x04 }, /* Multimedia */
117 { tHidd_PCI_SubClass
, 0x01 }, /* Audio */
119 { tHidd_PCI_VendorID
, vendorid
},
120 { tHidd_PCI_ProductID
, deviceid
},
124 struct pHidd_PCI_EnumDevices enummsg
=
126 mID
: OOP_GetMethodID(CLID_Hidd_PCI
, moHidd_PCI_EnumDevices
),
128 requirements
: (struct TagItem
*)&Reqs
,
131 ed
.prev_dev
= (OOP_Object
*)dev
;
134 OOP_DoMethod(pciobj
, (OOP_Msg
)msg
);
136 //KPrintF("ahi_pci_find_device: found_dev = %lx\n", ed.found_dev);
138 return (APTR
)ed
.found_dev
;
141 ULONG
pci_inl(ULONG addr
, struct HDAudioChip
*card
)
143 ULONG
*real_addr
= (ULONG
*) (card
->iobase
+ addr
); // card->iobase should be virtual
148 UWORD
pci_inw(ULONG addr
, struct HDAudioChip
*card
)
150 UWORD
*real_addr
= (UWORD
*) (card
->iobase
+ addr
);
155 UBYTE
pci_inb(ULONG addr
, struct HDAudioChip
*card
)
157 UBYTE
*real_addr
= (UBYTE
*) (card
->iobase
+ addr
);
162 void pci_outl(ULONG value
, ULONG addr
, struct HDAudioChip
*card
)
164 *((ULONG
*) (card
->iobase
+ addr
)) = value
;
167 void pci_outw(UWORD value
, ULONG addr
, struct HDAudioChip
*card
)
169 *((UWORD
*) (card
->iobase
+ addr
)) = value
;
172 void pci_outb(UBYTE value
, ULONG addr
, struct HDAudioChip
*card
)
174 *((UBYTE
*) (card
->iobase
+ addr
)) = value
;
178 void outb_setbits(UBYTE value
, ULONG addr
, struct HDAudioChip
*card
)
180 UBYTE data
= pci_inb(addr
, card
);
183 pci_outb(data
, addr
, card
);
187 void outb_clearbits(UBYTE value
, ULONG addr
, struct HDAudioChip
*card
)
189 UBYTE data
= pci_inb(addr
, card
);
192 pci_outb(data
, addr
, card
);
196 void outw_setbits(UWORD value
, ULONG addr
, struct HDAudioChip
*card
)
198 UWORD data
= pci_inw(addr
, card
);
201 pci_outw(data
, addr
, card
);
205 void outw_clearbits(UWORD value
, ULONG addr
, struct HDAudioChip
*card
)
207 UWORD data
= pci_inw(addr
, card
);
210 pci_outw(data
, addr
, card
);
214 void outl_setbits(ULONG value
, ULONG addr
, struct HDAudioChip
*card
)
216 ULONG data
= pci_inl(addr
, card
);
219 pci_outl(data
, addr
, card
);
223 void outl_clearbits(ULONG value
, ULONG addr
, struct HDAudioChip
*card
)
225 ULONG data
= pci_inl(addr
, card
);
228 pci_outl(data
, addr
, card
);
232 ULONG
inl_config(UBYTE reg
, APTR dev
)
234 struct pHidd_PCIDevice_ReadConfigLong msg
;
239 return OOP_DoMethod((OOP_Object
*)dev
, (OOP_Msg
)&msg
);
242 UWORD
inw_config(UBYTE reg
, APTR dev
)
244 struct pHidd_PCIDevice_ReadConfigWord msg
;
249 return OOP_DoMethod((OOP_Object
*)dev
, (OOP_Msg
)&msg
);
252 UBYTE
inb_config(UBYTE reg
, APTR dev
)
254 struct pHidd_PCIDevice_ReadConfigByte msg
;
259 return OOP_DoMethod(dev
, (OOP_Msg
)&msg
);
262 void outl_config(UBYTE reg
, ULONG val
, APTR dev
)
264 struct pHidd_PCIDevice_WriteConfigLong msg
;
270 OOP_DoMethod((OOP_Object
*)dev
, (OOP_Msg
)&msg
);
273 void outw_config(UBYTE reg
, UWORD val
, APTR dev
)
275 struct pHidd_PCIDevice_WriteConfigWord msg
;
281 OOP_DoMethod((OOP_Object
*)dev
, (OOP_Msg
)&msg
);
284 void outb_config(UBYTE reg
, UBYTE val
, APTR dev
)
286 struct pHidd_PCIDevice_WriteConfigByte msg
;
292 OOP_DoMethod((OOP_Object
*)dev
, (OOP_Msg
)&msg
);
295 ULONG
ahi_pci_get_irq(APTR dev
)
299 OOP_GetAttr((OOP_Object
*)dev
, aHidd_PCIDevice_INTLine
, &val
);
304 static void interrupt_code(HIDDT_IRQ_Handler
*irq
, HIDDT_IRQ_HwInfo
*hw
)
306 struct Interrupt
*i
= (struct Interrupt
*)irq
->h_Data
;
308 AROS_UFC3(void, i
->is_Code
,
309 AROS_UFCA(APTR
, i
->is_Data
, A1
),
310 AROS_UFCA(APTR
, i
->is_Code
, A5
),
311 AROS_UFCA(struct ExecBase
*, SysBase
, A6
));
315 BOOL
ahi_pci_add_intserver(struct Interrupt
*i
, APTR dev
)
317 struct pHidd_IRQ_AddHandler __msg__
, *msg
= &__msg__
;
320 OOP_GetAttr((OOP_Object
*)dev
, aHidd_PCIDevice_INTLine
, &val
);
322 inthandler
.h_Node
.ln_Pri
= 1;
323 inthandler
.h_Node
.ln_Name
= "HD Audio IRQ";
324 inthandler
.h_Code
= interrupt_code
;
325 inthandler
.h_Data
= i
;
327 msg
->mID
= OOP_GetMethodID(CLID_Hidd_IRQ
, moHidd_IRQ_AddHandler
);
328 msg
->handlerinfo
= &inthandler
;
331 OOP_DoMethod(irqobj
, (OOP_Msg
)msg
);
333 inthandler_added
= TRUE
;
338 void ahi_pci_rem_intserver(struct Interrupt
*i
, APTR dev
)
340 if (inthandler_added
)
342 struct pHidd_IRQ_RemHandler __msg__
=
344 mID
: OOP_GetMethodID(CLID_Hidd_IRQ
, moHidd_IRQ_RemHandler
),
345 handlerinfo
: &inthandler
,
348 OOP_DoMethod(irqobj
, (OOP_Msg
)msg
);
350 inthandler_added
= FALSE
;
353 KPrintF("ahi_pci_rem_intserver\n");
357 APTR
ahi_pci_get_base_address(WORD which
, APTR dev
)
365 attr
= aHidd_PCIDevice_Base0
;
369 attr
= aHidd_PCIDevice_Base1
;
373 attr
= aHidd_PCIDevice_Base2
;
377 attr
= aHidd_PCIDevice_Base3
;
381 attr
= aHidd_PCIDevice_Base4
;
385 attr
= aHidd_PCIDevice_Base5
;
392 OOP_GetAttr((OOP_Object
*)dev
, attr
, &val
);
394 //KPrintF("ahi_pci_get_base_address. Result %lx\n", val);
399 ULONG
ahi_pci_get_base_size(WORD which
, APTR dev
)
407 attr
= aHidd_PCIDevice_Size0
;
411 attr
= aHidd_PCIDevice_Size1
;
415 attr
= aHidd_PCIDevice_Size2
;
419 attr
= aHidd_PCIDevice_Size3
;
423 attr
= aHidd_PCIDevice_Size4
;
427 attr
= aHidd_PCIDevice_Size5
;
434 OOP_GetAttr((OOP_Object
*)dev
, attr
, &val
);
436 //KPrintF("ahi_pci_get_base_size. Result %lx\n", val);
444 ULONG
ahi_pci_get_type(WORD which
, APTR dev
)
452 attr
= aHidd_PCIDevice_Type0
;
456 attr
= aHidd_PCIDevice_Type1
;
460 attr
= aHidd_PCIDevice_Type2
;
464 attr
= aHidd_PCIDevice_Type3
;
468 attr
= aHidd_PCIDevice_Type4
;
472 attr
= aHidd_PCIDevice_Type5
;
479 OOP_GetAttr((OOP_Object
*)dev
, attr
, &val
);
481 //KPrintF("ahi_pci_get_type. Result %lx\n", val);