Build for AROS..
[AROS.git] / workbench / devs / AHI / Drivers / HDAudio / pci_aros.c
blob38430f0725821d84b9861cb8e0a2f5a665463d7c
1 #define __OOP_NOATTRBASES__
3 #include <config.h>
5 #include <utility/hooks.h>
6 #include <exec/interrupts.h>
7 #include <asm/io.h>
8 #include <oop/oop.h>
9 #include <hidd/pci.h>
10 #include <hidd/irq.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);
41 if (OOPBase)
43 __IHidd_PCIDev = OOP_ObtainAttrBase(IID_Hidd_PCIDevice);
44 if (__IHidd_PCIDev)
46 pciobj = OOP_NewObject(NULL, CLID_Hidd_PCI, NULL);
47 irqobj = OOP_NewObject(NULL, CLID_Hidd_IRQ, NULL);
49 if (pciobj && irqobj)
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);
59 return TRUE;
64 return FALSE;
67 void ahi_pci_exit(void)
69 if (irqobj)
70 OOP_DisposeObject(irqobj);
71 if (pciobj)
72 OOP_DisposeObject(pciobj);
73 if (__IHidd_PCIDev)
74 OOP_ReleaseAttrBase(IID_Hidd_PCIDevice);
75 if (OOPBase)
76 CloseLibrary(OOPBase);
79 struct enum_data
81 OOP_Object *prev_dev;
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))
90 AROS_USERFUNC_INIT
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;
99 AROS_USERFUNC_EXIT
103 APTR ahi_pci_find_device(ULONG vendorid, ULONG deviceid, APTR dev)
105 struct enum_data ed;
107 struct Hook FindHook =
109 h_Entry: (HOOKFUNC)Enumerator,
110 h_Data: &ed,
113 struct TagItem Reqs[] =
115 #if 0
116 { tHidd_PCI_Class , 0x04 }, /* Multimedia */
117 { tHidd_PCI_SubClass , 0x01 }, /* Audio */
118 #endif
119 { tHidd_PCI_VendorID , vendorid },
120 { tHidd_PCI_ProductID , deviceid },
121 { TAG_DONE , 0 },
124 struct pHidd_PCI_EnumDevices enummsg =
126 mID: OOP_GetMethodID(CLID_Hidd_PCI, moHidd_PCI_EnumDevices),
127 callback: &FindHook,
128 requirements: (struct TagItem *)&Reqs,
129 }, *msg = &enummsg;
131 ed.prev_dev = (OOP_Object *)dev;
132 ed.found_dev = 0;
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
145 return *(real_addr);
148 UWORD pci_inw(ULONG addr, struct HDAudioChip *card)
150 UWORD *real_addr = (UWORD *) (card->iobase + addr);
152 return *(real_addr);
155 UBYTE pci_inb(ULONG addr, struct HDAudioChip *card)
157 UBYTE *real_addr = (UBYTE *) (card->iobase + addr);
159 return *(real_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);
181 data |= value;
183 pci_outb(data, addr, card);
187 void outb_clearbits(UBYTE value, ULONG addr, struct HDAudioChip *card)
189 UBYTE data = pci_inb(addr, card);
190 data &= ~value;
192 pci_outb(data, addr, card);
196 void outw_setbits(UWORD value, ULONG addr, struct HDAudioChip *card)
198 UWORD data = pci_inw(addr, card);
199 data |= value;
201 pci_outw(data, addr, card);
205 void outw_clearbits(UWORD value, ULONG addr, struct HDAudioChip *card)
207 UWORD data = pci_inw(addr, card);
208 data &= ~value;
210 pci_outw(data, addr, card);
214 void outl_setbits(ULONG value, ULONG addr, struct HDAudioChip *card)
216 ULONG data = pci_inl(addr, card);
217 data |= value;
219 pci_outl(data, addr, card);
223 void outl_clearbits(ULONG value, ULONG addr, struct HDAudioChip *card)
225 ULONG data = pci_inl(addr, card);
226 data &= ~value;
228 pci_outl(data, addr, card);
232 ULONG inl_config(UBYTE reg, APTR dev)
234 struct pHidd_PCIDevice_ReadConfigLong msg;
236 msg.mID = mid_RL;
237 msg.reg = reg;
239 return OOP_DoMethod((OOP_Object *)dev, (OOP_Msg)&msg);
242 UWORD inw_config(UBYTE reg, APTR dev)
244 struct pHidd_PCIDevice_ReadConfigWord msg;
246 msg.mID = mid_RW;
247 msg.reg = reg;
249 return OOP_DoMethod((OOP_Object *)dev, (OOP_Msg)&msg);
252 UBYTE inb_config(UBYTE reg, APTR dev)
254 struct pHidd_PCIDevice_ReadConfigByte msg;
256 msg.mID = mid_RB;
257 msg.reg = reg;
259 return OOP_DoMethod(dev, (OOP_Msg)&msg);
262 void outl_config(UBYTE reg, ULONG val, APTR dev)
264 struct pHidd_PCIDevice_WriteConfigLong msg;
266 msg.mID = mid_WL;
267 msg.reg = reg;
268 msg.val = val;
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;
277 msg.mID = mid_WW;
278 msg.reg = reg;
279 msg.val = val;
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;
288 msg.mID = mid_WB;
289 msg.reg = reg;
290 msg.val = val;
292 OOP_DoMethod((OOP_Object *)dev, (OOP_Msg)&msg);
295 ULONG ahi_pci_get_irq(APTR dev)
297 IPTR val;
299 OOP_GetAttr((OOP_Object *)dev, aHidd_PCIDevice_INTLine, &val);
301 return (ULONG)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__;
318 IPTR val;
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;
329 msg->id = val;
331 OOP_DoMethod(irqobj, (OOP_Msg)msg);
333 inthandler_added = TRUE;
335 return 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,
346 }, *msg = &__msg__;
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)
359 OOP_AttrID attr = 0;
360 IPTR val = 0;
362 switch(which)
364 case 0:
365 attr = aHidd_PCIDevice_Base0;
366 break;
368 case 1:
369 attr = aHidd_PCIDevice_Base1;
370 break;
372 case 2:
373 attr = aHidd_PCIDevice_Base2;
374 break;
376 case 3:
377 attr = aHidd_PCIDevice_Base3;
378 break;
380 case 4:
381 attr = aHidd_PCIDevice_Base4;
382 break;
384 case 5:
385 attr = aHidd_PCIDevice_Base5;
386 break;
388 default:
389 return 0;
392 OOP_GetAttr((OOP_Object *)dev, attr, &val);
394 //KPrintF("ahi_pci_get_base_address. Result %lx\n", val);
396 return (APTR)val;
399 ULONG ahi_pci_get_base_size(WORD which, APTR dev)
401 OOP_AttrID attr = 0;
402 IPTR val = 0;
404 switch(which)
406 case 0:
407 attr = aHidd_PCIDevice_Size0;
408 break;
410 case 1:
411 attr = aHidd_PCIDevice_Size1;
412 break;
414 case 2:
415 attr = aHidd_PCIDevice_Size2;
416 break;
418 case 3:
419 attr = aHidd_PCIDevice_Size3;
420 break;
422 case 4:
423 attr = aHidd_PCIDevice_Size4;
424 break;
426 case 5:
427 attr = aHidd_PCIDevice_Size5;
428 break;
430 default:
431 return 0;
434 OOP_GetAttr((OOP_Object *)dev, attr, &val);
436 //KPrintF("ahi_pci_get_base_size. Result %lx\n", val);
438 return (ULONG)val;
444 ULONG ahi_pci_get_type(WORD which, APTR dev)
446 OOP_AttrID attr = 0;
447 IPTR val = 0;
449 switch(which)
451 case 0:
452 attr = aHidd_PCIDevice_Type0;
453 break;
455 case 1:
456 attr = aHidd_PCIDevice_Type1;
457 break;
459 case 2:
460 attr = aHidd_PCIDevice_Type2;
461 break;
463 case 3:
464 attr = aHidd_PCIDevice_Type3;
465 break;
467 case 4:
468 attr = aHidd_PCIDevice_Type4;
469 break;
471 case 5:
472 attr = aHidd_PCIDevice_Type5;
473 break;
475 default:
476 return 0;
479 OOP_GetAttr((OOP_Object *)dev, attr, &val);
481 //KPrintF("ahi_pci_get_type. Result %lx\n", val);
483 return (ULONG) val;