Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / hidds / nouveau / drm / drm-aros / drm_compat_funcs.c
blob10cf4186a36406d63881533bf6d8da90834e1ad8
1 /*
2 Copyright 2009, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include "drm_compat_funcs.h"
7 #include "drm_aros_config.h"
9 #define PIO_RESERVED (IPTR)0x40000UL
11 void iowrite32(u32 val, void * addr)
13 if ((IPTR)addr >= PIO_RESERVED)
14 writel(val, addr);
15 else
16 IMPLEMENT("PIO\n");
19 unsigned int ioread32(void * addr)
21 if ((IPTR)addr >= PIO_RESERVED)
22 return readl(addr);
23 else
24 IMPLEMENT("PIO\n");
26 return 0xffffffff;
29 void iowrite16(u16 val, void * addr)
31 if ((IPTR)addr >= PIO_RESERVED)
32 writew(val, addr);
33 else
34 IMPLEMENT("PIO\n");
37 unsigned int ioread16(void * addr)
39 if ((IPTR)addr >= PIO_RESERVED)
40 return readw(addr);
41 else
42 IMPLEMENT("PIO\n");
44 return 0xffff;
47 void iowrite8(u8 val, void * addr)
49 if ((IPTR)addr >= PIO_RESERVED)
50 writeb(val, addr);
51 else
52 IMPLEMENT("PIO\n");
55 unsigned int ioread8(void * addr)
57 if ((IPTR)addr >= PIO_RESERVED)
58 return readb(addr);
59 else
60 IMPLEMENT("PIO\n");
62 return 0xff;
65 /* Bit operations */
66 void clear_bit(int nr, volatile void * addr)
68 unsigned long mask = 1 << nr;
70 *(unsigned long*)addr &= ~mask;
73 void set_bit(int nr, volatile void *addr)
75 unsigned long mask = 1 << nr;
77 *(unsigned long*)addr |= mask;
80 int test_bit(int nr, volatile void *addr)
82 unsigned long mask = 1 << nr;
84 return (*(unsigned long*)addr) & mask;
87 /* Delay handling */
88 #include <aros/symbolsets.h>
89 #include <devices/timer.h>
90 struct MsgPort *p = NULL;
91 struct timerequest *io = NULL;
93 void udelay(unsigned long usecs)
95 /* Create local clone so that the function is task safe */
96 struct timerequest timerio;
97 struct MsgPort timermp;
99 memset(&timermp, 0, sizeof(timermp));
101 timermp.mp_Node.ln_Type = NT_MSGPORT;
102 timermp.mp_Flags = PA_SIGNAL;
103 timermp.mp_SigBit = SIGB_SINGLE;
104 timermp.mp_SigTask = FindTask(NULL);
105 NEWLIST(&timermp.mp_MsgList);
107 timerio = *io;
109 timerio.tr_node.io_Message.mn_Node.ln_Type = NT_REPLYMSG;
110 timerio.tr_node.io_Message.mn_ReplyPort = &timermp;
111 timerio.tr_node.io_Command = TR_ADDREQUEST;
112 timerio.tr_time.tv_secs = usecs / 1000000;
113 timerio.tr_time.tv_micro = usecs - (timerio.tr_time.tv_secs * 1000000);
115 SetSignal(0, SIGF_SINGLE);
117 DoIO((struct IORequest*)&timerio);
120 static BOOL init_timer()
122 p = CreateMsgPort();
124 if (!p)
125 return FALSE;
127 io = CreateIORequest(p, sizeof(struct timerequest));
129 if(!io)
131 DeleteMsgPort(p);
132 return FALSE;
135 if (OpenDevice("timer.device", UNIT_MICROHZ, (struct IORequest *)io, 0) != 0)
137 DeleteIORequest(io);
138 DeleteMsgPort(p);
141 return TRUE;
144 static BOOL deinit_timer()
146 if (io)
148 CloseDevice((struct IORequest *)io);
149 DeleteIORequest((struct IORequest *)io);
150 io = NULL;
153 if (p)
155 DeleteMsgPort(p);
156 p = NULL;
159 return TRUE;
162 ADD2INIT(init_timer, 5);
163 ADD2EXIT(deinit_timer, 5);
165 /* Page handling */
166 void __free_page(struct page * p)
168 if (p->allocated_buffer)
169 HIDDNouveauFree(p->allocated_buffer);
170 p->allocated_buffer = NULL;
171 p->address = NULL;
172 HIDDNouveauFree(p);
175 struct page * create_page_helper()
177 struct page * p;
178 p = HIDDNouveauAlloc(sizeof(*p));
179 p->allocated_buffer = HIDDNouveauAlloc(PAGE_SIZE + PAGE_SIZE - 1);
180 p->address = PAGE_ALIGN(p->allocated_buffer);
181 return p;
184 /* IDR handling */
185 int idr_pre_get_internal(struct idr *idp)
187 if (idp->size <= idp->occupied + idp->last_starting_id)
189 /* Create new table */
190 ULONG newsize = idp->size ? idp->size * 2 : 128;
191 IPTR * newtab = HIDDNouveauAlloc(newsize * sizeof(IPTR));
193 if (newtab == NULL)
194 return 0;
197 if (idp->pointers)
199 /* Copy old table into new */
200 CopyMem(idp->pointers, newtab, idp->size * sizeof(IPTR));
202 /* Release old table */
203 HIDDNouveauFree(idp->pointers);
206 idp->pointers = newtab;
207 idp->size = newsize;
210 return 1;
213 int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id)
215 int i = starting_id;
216 idp->last_starting_id = starting_id;
218 for(;i < idp->size;i++)
220 if (idp->pointers[i] == (IPTR)NULL)
222 *id = i;
223 idp->pointers[i] = (IPTR)ptr;
224 idp->occupied++;
225 return 0;
229 return -EAGAIN;
232 void *idr_find(struct idr *idp, int id)
234 if ((id < idp->size) && (id >= 0))
235 return (APTR)idp->pointers[id];
236 else
237 return NULL;
240 void idr_remove(struct idr *idp, int id)
242 if ((id < idp->size) && (id >= 0))
244 idp->pointers[id] = (IPTR)NULL;
245 idp->occupied--;
249 void idr_init(struct idr *idp)
251 idp->size = 0;
252 idp->pointers = NULL;
253 idp->occupied = 0;
254 idp->last_starting_id = 0;
257 /* PCI handling */
258 #include "drm_aros.h"
259 #include <aros/libcall.h>
260 #include <proto/oop.h>
261 #include <hidd/pci.h>
262 #include <hidd/hidd.h>
264 void *ioremap(resource_size_t offset, unsigned long size)
266 if (pciDriver)
268 struct pHidd_PCIDriver_MapPCI mappci,*msg = &mappci;
269 mappci.mID = OOP_GetMethodID(IID_Hidd_PCIDriver, moHidd_PCIDriver_MapPCI);
270 mappci.PCIAddress = (APTR)offset;
271 mappci.Length = size;
272 return (APTR)OOP_DoMethod(pciDriver, (OOP_Msg)msg);
274 else
276 bug("BUG: ioremap used without acquiring pciDriver\n");
277 return NULL;
281 void iounmap(void * addr)
283 if (pciDriver)
285 struct pHidd_PCIDriver_UnmapPCI unmappci,*msg=&unmappci;
287 unmappci.mID = OOP_GetMethodID(IID_Hidd_PCIDriver, moHidd_PCIDriver_UnmapPCI);
288 unmappci.CPUAddress = addr;
289 unmappci.Length = 0; /* This works on i386 but may create problems on other archs */
291 OOP_DoMethod(pciDriver, (OOP_Msg)msg);
295 resource_size_t pci_resource_start(struct pci_dev * pdev, unsigned int resource)
297 APTR start = (APTR)NULL;
298 switch(resource)
300 case(0): OOP_GetAttr((OOP_Object *)pdev->oopdev, aHidd_PCIDevice_Base0, (APTR)&start); break;
301 case(1): OOP_GetAttr((OOP_Object *)pdev->oopdev, aHidd_PCIDevice_Base1, (APTR)&start); break;
302 case(2): OOP_GetAttr((OOP_Object *)pdev->oopdev, aHidd_PCIDevice_Base2, (APTR)&start); break;
303 case(3): OOP_GetAttr((OOP_Object *)pdev->oopdev, aHidd_PCIDevice_Base3, (APTR)&start); break;
304 case(4): OOP_GetAttr((OOP_Object *)pdev->oopdev, aHidd_PCIDevice_Base4, (APTR)&start); break;
305 case(5): OOP_GetAttr((OOP_Object *)pdev->oopdev, aHidd_PCIDevice_Base5, (APTR)&start); break;
306 default: bug("ResourceID %d not supported\n", resource);
309 return (resource_size_t)start;
312 unsigned long pci_resource_len(struct pci_dev * pdev, unsigned int resource)
314 IPTR len = (IPTR)0;
316 if (pci_resource_start(pdev, resource) != 0)
319 * FIXME:
320 * The length reading is only correct when the resource actually exists.
321 * pci.hidd can however return a non 0 lenght for a resource that does
322 * not exsist. Possible fix in pci.hidd needed
325 switch(resource)
327 case(0): OOP_GetAttr((OOP_Object *)pdev->oopdev, aHidd_PCIDevice_Size0, (APTR)&len); break;
328 case(1): OOP_GetAttr((OOP_Object *)pdev->oopdev, aHidd_PCIDevice_Size1, (APTR)&len); break;
329 case(2): OOP_GetAttr((OOP_Object *)pdev->oopdev, aHidd_PCIDevice_Size2, (APTR)&len); break;
330 case(3): OOP_GetAttr((OOP_Object *)pdev->oopdev, aHidd_PCIDevice_Size3, (APTR)&len); break;
331 case(4): OOP_GetAttr((OOP_Object *)pdev->oopdev, aHidd_PCIDevice_Size4, (APTR)&len); break;
332 case(5): OOP_GetAttr((OOP_Object *)pdev->oopdev, aHidd_PCIDevice_Size5, (APTR)&len); break;
333 default: bug("ResourceID %d not supported\n", resource);
337 return len;
340 struct GetBusSlotEnumeratorData
342 IPTR Bus;
343 IPTR Dev;
344 IPTR Sub;
345 OOP_Object ** pciDevice;
348 AROS_UFH3(void, GetBusSlotEnumerator,
349 AROS_UFHA(struct Hook *, hook, A0),
350 AROS_UFHA(OOP_Object *, pciDevice, A2),
351 AROS_UFHA(APTR, message, A1))
353 AROS_USERFUNC_INIT
355 struct GetBusSlotEnumeratorData * data = hook->h_Data;
357 IPTR Bus;
358 IPTR Dev;
359 IPTR Sub;
361 if (*data->pciDevice)
362 return; /* Already found, should not happen */
364 /* Get the Device's properties */
365 OOP_GetAttr(pciDevice, aHidd_PCIDevice_Bus, &Bus);
366 OOP_GetAttr(pciDevice, aHidd_PCIDevice_Dev, &Dev);
367 OOP_GetAttr(pciDevice, aHidd_PCIDevice_Sub, &Sub);
369 if (data->Bus == Bus &&
370 data->Dev == Dev &&
371 data->Sub == Sub)
373 (*data->pciDevice) = pciDevice;
376 AROS_USERFUNC_EXIT
378 void * pci_get_bus_and_slot(unsigned int bus, unsigned int dev, unsigned int fun)
380 OOP_Object * pciDevice = NULL;
382 if (pciBus)
384 struct GetBusSlotEnumeratorData data = {
385 Bus: bus,
386 Dev: dev,
387 Sub: fun,
388 pciDevice: &pciDevice,
391 struct Hook FindHook = {
392 h_Entry: (IPTR (*)())GetBusSlotEnumerator,
393 h_Data: &data,
396 struct TagItem Requirements[] = {
397 { TAG_DONE, 0UL }
400 struct pHidd_PCI_EnumDevices enummsg = {
401 mID: OOP_GetMethodID(IID_Hidd_PCI, moHidd_PCI_EnumDevices),
402 callback: &FindHook,
403 requirements: (struct TagItem*)&Requirements,
404 }, *msg = &enummsg;
406 OOP_DoMethod(pciBus, (OOP_Msg)msg);
409 return pciDevice;
412 int pci_read_config_word(struct pci_dev * pdev, int where, u16 *val)
414 struct pHidd_PCIDevice_ReadConfigWord rcwmsg = {
415 mID: OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigWord),
416 reg: (UBYTE)where,
417 }, *msg = &rcwmsg;
419 *val = (UWORD)OOP_DoMethod((OOP_Object*)pdev->oopdev, (OOP_Msg)msg);
420 D(bug("pci_read_config_word: %d -> %d\n", where, *val));
422 return 0;
425 int pci_read_config_dword(struct pci_dev * pdev, int where, u32 *val)
427 struct pHidd_PCIDevice_ReadConfigLong rclmsg = {
428 mID: OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigLong),
429 reg: (UBYTE)where,
430 }, *msg = &rclmsg;
432 *val = (ULONG)OOP_DoMethod((OOP_Object*)pdev->oopdev, (OOP_Msg)msg);
433 D(bug("pci_read_config_dword: %d -> %d\n", where, *val));
435 return 0;
438 int pci_write_config_dword(struct pci_dev * pdev, int where, u32 val)
440 struct pHidd_PCIDevice_WriteConfigLong wclmsg = {
441 mID: OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigLong),
442 reg: (UBYTE)where,
443 val: val,
444 }, *msg = &wclmsg;
446 OOP_DoMethod((OOP_Object*)pdev->oopdev, (OOP_Msg)msg);
447 D(bug("pci_write_config_dword: %d -> %d\n", where, val));
449 return 0;
452 int pci_is_pcie(struct pci_dev * pdev)
454 IPTR PCIECap;
455 OOP_GetAttr((OOP_Object *)pdev->oopdev, aHidd_PCIDevice_CapabilityPCIE, (APTR)&PCIECap);
456 return PCIECap;
459 #include <hidd/agp.h>
461 /* AGP handling */
462 struct agp_bridge_data * global_agp_bridge = NULL; /* TODO: implement freeing */
463 struct Library * HiddAgpBase = NULL; /* TODO: Implement freeing */
464 OOP_AttrBase HiddAGPBridgeDeviceAttrBase = 0; /* TODO: Implement freeing */
466 struct agp_bridge_data *agp_backend_acquire(void * dev)
468 /* TODO:
469 if no bridge return NULL
470 if already acquired return NULL, else acquire
472 return agp_find_bridge(dev);
475 void agp_backend_release(struct agp_bridge_data * bridge)
477 /* TODO: release acquired lock */
480 void agp_free_memory(struct agp_memory * mem)
482 HIDDNouveauFree(mem->pages);
483 HIDDNouveauFree(mem);
486 struct agp_memory *agp_allocate_memory(struct agp_bridge_data * bridge,
487 size_t num_pages , u32 type)
489 if ((type != AGP_USER_MEMORY) && (type != AGP_USER_CACHED_MEMORY))
491 IMPLEMENT("Unsupported memory type: %d\n", type);
492 return NULL;
495 struct agp_memory * mem = HIDDNouveauAlloc(sizeof(struct agp_memory));
496 mem->pages = HIDDNouveauAlloc(sizeof(struct page *) * num_pages);
497 mem->page_count = 0; /* Not a typo, will be filled later */
498 mem->type = type;
499 mem->is_flushed = FALSE;
500 mem->is_bound = FALSE;
501 mem->pg_start = 0;
502 return mem;
505 int agp_copy_info(struct agp_bridge_data * bridge, struct agp_kern_info * info)
507 info->chipset = SUPPORTED;
508 info->cant_use_aperture = 0;
509 info->page_mask = ~0UL;
510 if (bridge->mode & (1<<3) /* AGPSTAT_MODE_3_0 */)
511 info->mode = bridge->mode & ~(0x00ff00c4); /* AGP3_RESERVED_MASK */
512 else
513 info->mode = bridge->mode & ~(0x00fffcc8); /* AGP2_RESERVED_MASK */
515 info->aper_base = (unsigned long)bridge->aperturebase;
516 info->aper_size = (unsigned long)bridge->aperturesize;
518 return 0;
521 struct agp_bridge_data * agp_find_bridge(void * dev)
523 OOP_Object * agpbus = NULL;
525 if (global_agp_bridge)
526 return global_agp_bridge;
528 if (!HiddAgpBase)
530 HiddAgpBase = OpenLibrary("agp.hidd", 1);
531 HiddAGPBridgeDeviceAttrBase = OOP_ObtainAttrBase((STRPTR)IID_Hidd_AGPBridgeDevice);
534 /* Get AGP bus object */
535 agpbus = OOP_NewObject(NULL, CLID_Hidd_AGP, NULL);
537 if(agpbus)
539 struct pHidd_AGP_GetBridgeDevice gbdmsg = {
540 mID : OOP_GetMethodID(IID_Hidd_AGP, moHidd_AGP_GetBridgeDevice)
542 OOP_Object * bridgedevice = NULL;
544 bridgedevice = (OOP_Object*)OOP_DoMethod(agpbus, (OOP_Msg)&gbdmsg);
546 OOP_DisposeObject(agpbus);
548 /* AGP bridge was found and initialized */
549 if (bridgedevice)
551 IPTR mode = 0, aperbase = 0, apersize = 0;
553 global_agp_bridge = HIDDNouveauAlloc(sizeof(struct agp_bridge_data));
554 global_agp_bridge->agpbridgedevice = (IPTR)bridgedevice;
556 OOP_GetAttr(bridgedevice, aHidd_AGPBridgeDevice_Mode, (APTR)&mode);
557 global_agp_bridge->mode = mode;
559 OOP_GetAttr(bridgedevice, aHidd_AGPBridgeDevice_ApertureBase, (APTR)&aperbase);
560 global_agp_bridge->aperturebase = aperbase;
562 OOP_GetAttr(bridgedevice, aHidd_AGPBridgeDevice_ApertureSize, (APTR)&apersize);
563 global_agp_bridge->aperturesize = apersize;
567 return global_agp_bridge;
570 void agp_enable(struct agp_bridge_data * bridge, u32 mode)
572 if (!bridge || !bridge->agpbridgedevice)
573 return;
575 struct pHidd_AGPBridgeDevice_Enable emsg = {
576 mID: OOP_GetMethodID(IID_Hidd_AGPBridgeDevice, moHidd_AGPBridgeDevice_Enable),
577 requestedmode: mode
580 OOP_DoMethod((OOP_Object *)bridge->agpbridgedevice, (OOP_Msg)&emsg);
583 int agp_bind_memory(struct agp_memory * mem, off_t offset)
585 if (!mem || mem->is_bound)
586 return -EINVAL;
588 if ((mem->type != AGP_USER_MEMORY) && (mem->type != AGP_USER_CACHED_MEMORY))
590 IMPLEMENT("Unsupported memory type: %d\n", mem->type);
591 return -EINVAL;
594 if (!mem->is_flushed)
596 /* TODO: Flush memory */
597 mem->is_flushed = TRUE;
600 /* TODO: agp_map_memory */
601 /* TODO: Move flush/map into bind call on the side of agp.hidd */
603 struct pHidd_AGPBridgeDevice_BindMemory bmmsg = {
604 mID: OOP_GetMethodID(IID_Hidd_AGPBridgeDevice, moHidd_AGPBridgeDevice_BindMemory),
605 address: (IPTR)(mem->pages[0]->address),
606 size: mem->page_count * PAGE_SIZE,
607 offset: offset,
608 type: (mem->type == AGP_USER_MEMORY ? vHidd_AGP_NormalMemory : vHidd_AGP_CachedMemory)
611 OOP_DoMethod((OOP_Object *)global_agp_bridge->agpbridgedevice, (OOP_Msg)&bmmsg);
613 mem->is_bound = TRUE;
614 mem->pg_start = offset;
615 return 0;
618 int agp_unbind_memory(struct agp_memory * mem)
620 if (!mem || !mem->is_bound)
621 return -EINVAL;
623 struct pHidd_AGPBridgeDevice_UnBindMemory ubmmsg = {
624 mID: OOP_GetMethodID(IID_Hidd_AGPBridgeDevice, moHidd_AGPBridgeDevice_UnBindMemory),
625 offset: mem->pg_start,
626 size: mem->page_count * PAGE_SIZE,
629 OOP_DoMethod((OOP_Object *)global_agp_bridge->agpbridgedevice, (OOP_Msg)&ubmmsg);
631 /* TODO: agp_unmap_memory */
633 mem->is_bound = FALSE;
634 mem->pg_start = 0;
635 return 0;
638 void agp_flush_chipset(struct agp_bridge_data * bridge)
640 if (!bridge || !bridge->agpbridgedevice)
641 return;
643 struct pHidd_AGPBridgeDevice_FlushChipset fcmsg = {
644 mID: OOP_GetMethodID(IID_Hidd_AGPBridgeDevice, moHidd_AGPBridgeDevice_FlushChipset),
647 OOP_DoMethod((OOP_Object *)bridge->agpbridgedevice, (OOP_Msg)&fcmsg);
650 /* jiffies handling */
651 #include <sys/time.h>
653 /* jiffies are supposed to be very precise time value. They are implemented
654 as rather very unprecise */
655 unsigned long get_jiffies()
657 struct timeval tv;
658 unsigned long val = 0;
660 gettimeofday(&tv, NULL);
662 val = tv.tv_sec * 1000000 + tv.tv_usec; /* Yes, overflow */
664 /* TODO: Maybe make sure that each call to get_jiffies returns a different value? */
666 return val;
669 /* I2C handling */
670 #include <hidd/i2c.h>
672 OOP_AttrBase HiddI2CDeviceAttrBase = 0; /* TODO: Implement freeing */
674 int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
676 /* FIXME: This function is not generic. It has hardcoded cases that are present in nouveau */
677 if (adap->i2cdriver == (IPTR)0)
679 bug("ERROR: i2c_transfer called without driver present\n");
680 return 0;
683 if (HiddI2CDeviceAttrBase == 0)
684 HiddI2CDeviceAttrBase = OOP_ObtainAttrBase((STRPTR)IID_Hidd_I2CDevice);
686 if (HiddI2CDeviceAttrBase == 0)
688 bug("ERROR: i2c_trasfer not able to obtain HiddI2CDeviceAttrBase\n");
689 return 0;
692 /* Go through supported cases */
693 if ((num == 2) && (msgs[0].addr == 0x50) && (msgs[1].addr == 0x50) && (msgs[0].len == 1) && (msgs[1].len == 1))
695 /* This is probing for DDC */
696 D(bug("i2c_transfer - probing for DDC\n"));
697 if (HIDD_I2C_ProbeAddress((OOP_Object *)adap->i2cdriver, 0xa0)) /* AROS has shifted addresses (<< 1) */
698 return 2;
699 else
700 return 0;
702 else if ((num == 2) && (msgs[0].addr == 0x75) && (msgs[1].addr == 0x75) && (msgs[0].len == 1) && (msgs[1].len == 1))
704 /* This is probing for some hardware related to TV output on nv04 */
705 D(bug("i2c_transfer - probing for some hardware related to TV output on nv04\n"));
706 if (HIDD_I2C_ProbeAddress((OOP_Object *)adap->i2cdriver, 0xea)) /* AROS has shifted addresses (<< 1) */
707 return 2;
708 else
709 return 0;
711 else if ((num == 2) && (msgs[0].addr == 0x50) && (msgs[1].addr == 0x50) && (msgs[0].len == 1) && (msgs[1].len != 1))
713 /* This is reading data from DDC */
714 struct pHidd_I2CDevice_WriteRead msg;
715 BOOL result = FALSE;
717 struct TagItem attrs[] =
719 { aHidd_I2CDevice_Driver, (IPTR)adap->i2cdriver },
720 { aHidd_I2CDevice_Address, 0xa0 },
721 { aHidd_I2CDevice_Name, (IPTR)"Read DDC" },
722 { TAG_DONE, 0UL }
725 D(bug("i2c_transfer - reading from DDC\n"));
727 OOP_Object *obj = OOP_NewObject(NULL, CLID_Hidd_I2CDevice, attrs);
729 msg.mID = OOP_GetMethodID((STRPTR)IID_Hidd_I2CDevice, moHidd_I2CDevice_WriteRead);
730 msg.readBuffer = msgs[1].buf;
731 msg.readLength = msgs[1].len;
732 msg.writeBuffer = msgs[0].buf;
733 msg.writeLength = msgs[0].len;
735 result = OOP_DoMethod(obj, &msg.mID);
737 OOP_DisposeObject(obj);
739 if (result)
740 return 2;
741 else
742 return 0;
744 else if ((num == 2) && (msgs[0].addr == 0x54) && (msgs[1].addr == 0x54) && (msgs[0].len == 1) && (msgs[1].len == 1))
746 /* This is reading data from register 0x54 */
747 struct pHidd_I2CDevice_WriteRead msg;
748 BOOL result = FALSE;
750 struct TagItem attrs[] =
752 { aHidd_I2CDevice_Driver, (IPTR)adap->i2cdriver },
753 { aHidd_I2CDevice_Address, 0xa8 },
754 { aHidd_I2CDevice_Name, (IPTR)"Read Register" },
755 { TAG_DONE, 0UL }
758 D(bug("i2c_transfer - reading from register 0x54\n"));
760 OOP_Object *obj = OOP_NewObject(NULL, CLID_Hidd_I2CDevice, attrs);
762 msg.mID = OOP_GetMethodID((STRPTR)IID_Hidd_I2CDevice, moHidd_I2CDevice_WriteRead);
763 msg.readBuffer = msgs[1].buf;
764 msg.readLength = msgs[1].len;
765 msg.writeBuffer = msgs[0].buf;
766 msg.writeLength = msgs[0].len;
768 result = OOP_DoMethod(obj, &msg.mID);
770 OOP_DisposeObject(obj);
772 if (result)
773 return 2;
774 else
775 return 0;
777 else
779 /* Not supported case */
780 bug("i2c_transfer case not supported: num = %d\n", num);
783 /* Failure */
784 return 0;
787 int i2c_del_adapter(struct i2c_adapter * adap)
789 IMPLEMENT("\n");
790 return 0;
793 /* Other */
794 unsigned int hweight32(unsigned int number)
796 unsigned int result = 0;
797 int i = 0;
799 for (i = 0; i < 32; i++)
801 if (number & 0x1) result++;
802 number >>= 1;
805 return result;
808 unsigned int hweight8(unsigned int number)
810 unsigned int result = 0;
811 int i = 0;
813 for (i = 0; i < 8; i++)
815 if (number & 0x1) result++;
816 number >>= 1;
819 return result;