Fix IO memory access .. SB128 driver makes noises in VMWare - CMI is untested (Curren...
[AROS.git] / workbench / devs / AHI / Drivers / CMI8738 / pci_aros.c
blob097d7d1cd5260be566ff35a35c1a8068e4da152f
1 #define __OOP_NOATTRBASES__
4 #include <utility/hooks.h>
5 #include <exec/interrupts.h>
6 #include <aros/macros.h>
7 #include <aros/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;
23 static OOP_AttrBase __IHidd_PCIDev;
24 static OOP_Object *pciobj, *irqobj;
26 static OOP_MethodID mid_RB;
27 static OOP_MethodID mid_RW;
28 static OOP_MethodID mid_RL;
30 static OOP_MethodID mid_WB;
31 static OOP_MethodID mid_WW;
32 static OOP_MethodID mid_WL;
34 static HIDDT_IRQ_Handler inthandler;
35 static BOOL inthandler_added;
37 BOOL ahi_pci_init(struct DriverBase* AHIsubBase)
39 OOPBase = OpenLibrary(AROSOOP_NAME, 0);
40 if (OOPBase)
42 __IHidd_PCIDev = OOP_ObtainAttrBase(IID_Hidd_PCIDevice);
43 if (__IHidd_PCIDev)
45 pciobj = OOP_NewObject(NULL, CLID_Hidd_PCI, NULL);
46 irqobj = OOP_NewObject(NULL, CLID_Hidd_IRQ, NULL);
48 if (pciobj && irqobj)
50 mid_RB = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
51 mid_RW = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigWord);
52 mid_RL = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigLong);
54 mid_WB = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
55 mid_WW = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigWord);
56 mid_WL = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigLong);
58 return TRUE;
63 return FALSE;
66 void ahi_pci_exit(void)
68 if (irqobj)
69 OOP_DisposeObject(irqobj);
70 if (pciobj)
71 OOP_DisposeObject(pciobj);
72 if (__IHidd_PCIDev)
73 OOP_ReleaseAttrBase(IID_Hidd_PCIDevice);
74 if (OOPBase)
75 CloseLibrary(OOPBase);
78 struct enum_data
80 OOP_Object *prev_dev;
81 OOP_Object *found_dev;
84 static AROS_UFH3(void, Enumerator,
85 AROS_UFHA(struct Hook *, hook, A0),
86 AROS_UFHA(OOP_Object *, device, A2),
87 AROS_UFHA(APTR, msg, A1))
89 AROS_USERFUNC_INIT
91 struct enum_data *ed = (struct enum_data *)hook->h_Data;
93 if ((ed->found_dev == 0) && (device != ed->prev_dev))
95 ed->found_dev = device;
98 AROS_USERFUNC_EXIT
102 APTR ahi_pci_find_device(ULONG vendorid, ULONG deviceid, APTR dev)
104 struct enum_data ed;
106 struct Hook FindHook =
108 h_Entry: (HOOKFUNC)Enumerator,
109 h_Data: &ed,
112 struct TagItem Reqs[] =
114 #if 0
115 { tHidd_PCI_Class , 0x04 }, /* Multimedia */
116 { tHidd_PCI_SubClass , 0x01 }, /* Audio */
117 #endif
118 { tHidd_PCI_VendorID , vendorid },
119 { tHidd_PCI_ProductID , deviceid },
120 { TAG_DONE , 0 },
123 struct pHidd_PCI_EnumDevices enummsg =
125 mID: OOP_GetMethodID(CLID_Hidd_PCI, moHidd_PCI_EnumDevices),
126 callback: &FindHook,
127 requirements: (struct TagItem *)&Reqs,
128 }, *msg = &enummsg;
130 ed.prev_dev = (OOP_Object *)dev;
131 ed.found_dev = 0;
133 OOP_DoMethod(pciobj, (OOP_Msg)msg);
135 //KPrintF("ahi_pci_find_device: found_dev = %lx\n", ed.found_dev);
137 return (APTR)ed.found_dev;
140 ULONG pci_inl(ULONG addr, struct CMI8738_DATA *card)
142 return LONGIN(card->iobase + addr);
145 UWORD pci_inw(ULONG addr, struct CMI8738_DATA *card)
147 return WORDIN(card->iobase + addr);
150 UBYTE pci_inb(ULONG addr, struct CMI8738_DATA *card)
152 return BYTEIN(card->iobase + addr);
155 void pci_outl(ULONG value, ULONG addr, struct CMI8738_DATA *card)
157 LONGOUT(card->iobase + addr, value);
160 void pci_outw(UWORD value, ULONG addr, struct CMI8738_DATA *card)
162 WORDOUT(card->iobase + addr, value);
165 void pci_outb(UBYTE value, ULONG addr, struct CMI8738_DATA *card)
167 BYTEOUT(card->iobase + addr, value);
170 void outb_setbits(UBYTE value, ULONG addr, struct CMI8738_DATA *card)
172 UBYTE data = pci_inb(addr, card);
173 data |= value;
175 pci_outb(data, addr, card);
179 void outb_clearbits(UBYTE value, ULONG addr, struct CMI8738_DATA *card)
181 UBYTE data = pci_inb(addr, card);
182 data &= ~value;
184 pci_outb(data, addr, card);
188 void outw_setbits(UWORD value, ULONG addr, struct CMI8738_DATA *card)
190 UWORD data = pci_inw(addr, card);
191 data |= value;
193 pci_outw(data, addr, card);
197 void outw_clearbits(UWORD value, ULONG addr, struct CMI8738_DATA *card)
199 UWORD data = pci_inw(addr, card);
200 data &= ~value;
202 pci_outw(data, addr, card);
206 void outl_setbits(ULONG value, ULONG addr, struct CMI8738_DATA *card)
208 ULONG data = pci_inl(addr, card);
209 data |= value;
211 pci_outl(data, addr, card);
215 void outl_clearbits(ULONG value, ULONG addr, struct CMI8738_DATA *card)
217 ULONG data = pci_inl(addr, card);
218 data &= ~value;
220 pci_outl(data, addr, card);
224 ULONG inl_config(UBYTE reg, APTR dev)
226 struct pHidd_PCIDevice_ReadConfigLong msg;
228 msg.mID = mid_RL;
229 msg.reg = reg;
231 return OOP_DoMethod((OOP_Object *)dev, (OOP_Msg)&msg);
234 UWORD inw_config(UBYTE reg, APTR dev)
236 struct pHidd_PCIDevice_ReadConfigWord msg;
238 msg.mID = mid_RW;
239 msg.reg = reg;
241 return OOP_DoMethod((OOP_Object *)dev, (OOP_Msg)&msg);
244 UBYTE inb_config(UBYTE reg, APTR dev)
246 struct pHidd_PCIDevice_ReadConfigByte msg;
248 msg.mID = mid_RB;
249 msg.reg = reg;
251 return OOP_DoMethod(dev, (OOP_Msg)&msg);
254 void outl_config(UBYTE reg, ULONG val, APTR dev)
256 struct pHidd_PCIDevice_WriteConfigLong msg;
258 msg.mID = mid_WL;
259 msg.reg = reg;
260 msg.val = val;
262 OOP_DoMethod((OOP_Object *)dev, (OOP_Msg)&msg);
265 void outw_config(UBYTE reg, UWORD val, APTR dev)
267 struct pHidd_PCIDevice_WriteConfigWord msg;
269 msg.mID = mid_WW;
270 msg.reg = reg;
271 msg.val = val;
273 OOP_DoMethod((OOP_Object *)dev, (OOP_Msg)&msg);
276 void outb_config(UBYTE reg, UBYTE val, APTR dev)
278 struct pHidd_PCIDevice_WriteConfigByte msg;
280 msg.mID = mid_WB;
281 msg.reg = reg;
282 msg.val = val;
284 OOP_DoMethod((OOP_Object *)dev, (OOP_Msg)&msg);
287 ULONG ahi_pci_get_irq(APTR dev)
289 IPTR val;
291 OOP_GetAttr((OOP_Object *)dev, aHidd_PCIDevice_INTLine, &val);
293 return (ULONG)val;
296 static void interrupt_code(HIDDT_IRQ_Handler *irq, HIDDT_IRQ_HwInfo *hw)
298 struct Interrupt *i = (struct Interrupt *)irq->h_Data;
300 AROS_UFC3(void, i->is_Code,
301 AROS_UFCA(APTR, i->is_Data, A1),
302 AROS_UFCA(APTR, i->is_Code, A5),
303 AROS_UFCA(struct ExecBase *, SysBase, A6));
307 BOOL ahi_pci_add_intserver(struct Interrupt *i, APTR dev)
309 struct pHidd_IRQ_AddHandler __msg__, *msg = &__msg__;
310 IPTR val;
312 OOP_GetAttr((OOP_Object *)dev, aHidd_PCIDevice_INTLine, &val);
314 inthandler.h_Node.ln_Pri = 1;
315 inthandler.h_Node.ln_Name = "HD Audio IRQ";
316 inthandler.h_Code = interrupt_code;
317 inthandler.h_Data = i;
319 msg->mID = OOP_GetMethodID(CLID_Hidd_IRQ, moHidd_IRQ_AddHandler);
320 msg->handlerinfo = &inthandler;
321 msg->id = val;
323 OOP_DoMethod(irqobj, (OOP_Msg)msg);
325 inthandler_added = TRUE;
327 return TRUE;
330 void ahi_pci_rem_intserver(struct Interrupt *i, APTR dev)
332 if (inthandler_added)
334 struct pHidd_IRQ_RemHandler __msg__ =
336 mID: OOP_GetMethodID(CLID_Hidd_IRQ, moHidd_IRQ_RemHandler),
337 handlerinfo: &inthandler,
338 }, *msg = &__msg__;
340 OOP_DoMethod(irqobj, (OOP_Msg)msg);
342 inthandler_added = FALSE;
345 KPrintF("ahi_pci_rem_intserver\n");
349 APTR ahi_pci_get_base_address(WORD which, APTR dev)
351 OOP_AttrID attr = 0;
352 IPTR val = 0;
354 switch(which)
356 case 0:
357 attr = aHidd_PCIDevice_Base0;
358 break;
360 case 1:
361 attr = aHidd_PCIDevice_Base1;
362 break;
364 case 2:
365 attr = aHidd_PCIDevice_Base2;
366 break;
368 case 3:
369 attr = aHidd_PCIDevice_Base3;
370 break;
372 case 4:
373 attr = aHidd_PCIDevice_Base4;
374 break;
376 case 5:
377 attr = aHidd_PCIDevice_Base5;
378 break;
380 default:
381 return 0;
384 OOP_GetAttr((OOP_Object *)dev, attr, &val);
386 //KPrintF("ahi_pci_get_base_address. Result %lx\n", val);
388 return (APTR)val;
391 ULONG ahi_pci_get_base_size(WORD which, APTR dev)
393 OOP_AttrID attr = 0;
394 IPTR val = 0;
396 switch(which)
398 case 0:
399 attr = aHidd_PCIDevice_Size0;
400 break;
402 case 1:
403 attr = aHidd_PCIDevice_Size1;
404 break;
406 case 2:
407 attr = aHidd_PCIDevice_Size2;
408 break;
410 case 3:
411 attr = aHidd_PCIDevice_Size3;
412 break;
414 case 4:
415 attr = aHidd_PCIDevice_Size4;
416 break;
418 case 5:
419 attr = aHidd_PCIDevice_Size5;
420 break;
422 default:
423 return 0;
426 OOP_GetAttr((OOP_Object *)dev, attr, &val);
428 //KPrintF("ahi_pci_get_base_size. Result %lx\n", val);
430 return (ULONG)val;
436 ULONG ahi_pci_get_type(WORD which, APTR dev)
438 OOP_AttrID attr = 0;
439 IPTR val = 0;
441 switch(which)
443 case 0:
444 attr = aHidd_PCIDevice_Type0;
445 break;
447 case 1:
448 attr = aHidd_PCIDevice_Type1;
449 break;
451 case 2:
452 attr = aHidd_PCIDevice_Type2;
453 break;
455 case 3:
456 attr = aHidd_PCIDevice_Type3;
457 break;
459 case 4:
460 attr = aHidd_PCIDevice_Type4;
461 break;
463 case 5:
464 attr = aHidd_PCIDevice_Type5;
465 break;
467 default:
468 return 0;
471 OOP_GetAttr((OOP_Object *)dev, attr, &val);
473 //KPrintF("ahi_pci_get_type. Result %lx\n", val);
475 return (ULONG) val;