/*********************************************************** * Name: vc_cec_get_topology * * Arguments: * pointer to topology struct * * Description * Get the topology * * Returns: if the command is successful (zero) or not (non-zero) * If successful, the topology will be set, otherwise it is unchanged * A topology with 1 device (us) means CEC is not supported * If there is no topology available, this also returns a failure. ***********************************************************/ VCHPRE_ int VCHPOST_ vc_cec_get_topology( VC_CEC_TOPOLOGY_T* topology) { int32_t success = cecservice_send_command( VC_CEC_GET_TOPOLOGY, NULL, 0, 1); if(success == 0) { success = cecservice_wait_for_bulk_receive(cecservice_client.topology, sizeof(VC_CEC_TOPOLOGY_T)); } if(success == 0) { int i; cecservice_client.topology->active_mask = VC_VTOH16(cecservice_client.topology->active_mask); cecservice_client.topology->num_devices = VC_VTOH16(cecservice_client.topology->num_devices); for(i = 0; i < 15; i++) { cecservice_client.topology->device_attr[i] = VC_VTOH32(cecservice_client.topology->device_attr[i]); } memcpy(topology, cecservice_client.topology, sizeof(VC_CEC_TOPOLOGY_T)); } return success; }
int read_header (void) { // Read up to vin_int_req. int status; unsigned int i; int offset = (uint32_t)&vc_sharedmem_header.vin_int_req - (uint32_t)&vc_sharedmem_header; status = vc_host_read_consecutive(&vc_sharedmem_header, vc_interface_base, offset, 0); vc_assert(status == 0); for (i = 0; i < sizeof(vc_sharedmem_header.iface)/sizeof(uint16_t); i++) vc_sharedmem_header.iface[i] = VC_VTOH16(vc_sharedmem_header.iface[i]); return status; }
void CB_AudioFrameReceived( FRMFWD_FRAME_T *fwdFrame, unsigned int lengthinbyte, int streamNum ) { int i, available_space; short * datap, *dstp; int flag = 0; int numpair = fwdFrame->info.data_len / 4; int spaceRequired = numpair; if( needStereoComb == 0 ) { spaceRequired = numpair * 2; } /* senity check */ if( fwdFrame != (FRMFWD_FRAME_T *)pktbufp ) { printk("the incoming ptr 0x%x doesn't match the local copy 0x%x\n", (unsigned int)fwdFrame, (unsigned int)pktbufp ); } if( startplay == 0 ) { printk("start play not received yet, why are we receiving data %d?\n", numpair); } datap = (short *)&fwdFrame->data[0]; #if VC_AUDIO_TONEDEBUG for( i=0; i < numpair; i++ ) { datap[0] = testData[tempdataIndex]; datap[1] = testData[tempdataIndex]; tempdataIndex++; if( tempdataIndex >= 48 ) { tempdataIndex = 0; } datap+= 2; } datap = (short *)&fwdFrame->data[0]; #endif dstp = &samplebufp[audio_writeIdx]; /* check if we have enought space to receive the message */ if( audio_writeIdx < audio_readIdx ) { available_space = audio_readIdx - audio_writeIdx; } else { available_space = ( ((MAX_NUM_SAMPLE_PAIRS*2) - audio_writeIdx) + audio_readIdx ); } if( available_space < spaceRequired ) { printk("not enough space for incoming packets: ava %d, asked %d\n", available_space, spaceRequired ); } else { /* convert from stereo to mono and write it so pcm playout buffer */ int first_part = ((MAX_NUM_SAMPLE_PAIRS*2) - audio_writeIdx); int second_part = 0; if( first_part > spaceRequired ) { first_part = spaceRequired; } else { second_part = spaceRequired - first_part; } if( needStereoComb ) { for( i = 0; i < first_part; i++ ) { dstp[i] = (short)(( (int)((short)VC_VTOH16(datap[0])) + (int)((short)VC_VTOH16(datap[1])) )/ 2); flag |= dstp[i]; datap += 2; } if( second_part > 0 ) { dstp = samplebufp; for( i = 0; i < second_part; i++ ) { dstp[i] = (short)(( (int)((short)VC_VTOH16(datap[0])) + (int)((short)VC_VTOH16(datap[1])) )/ 2); flag |= dstp[i]; datap += 2; } } } else { /* playing out stereo samples, do not have to combine the left and right channel input */ for( i=0; i < first_part; i++ ) { dstp[i] = (short)(VC_VTOH16(datap[i])); } datap+= first_part; if( second_part > 0 ) { dstp = samplebufp; for( i=0; i < second_part; i++ ) { dstp[i] = (short)(VC_VTOH16(datap[i])); } } } /* take care of buffer wrap around */ audio_writeIdx += spaceRequired; if( audio_writeIdx >= (MAX_NUM_SAMPLE_PAIRS*2) ) { audio_writeIdx = second_part; } } /* release the packet for next incoming packet */ pktused = 0; }
/****************************************************************************** NAME vc_interface_init SYNOPSIS int vc_interface_init() FUNCTION Initialise the host side of the interface. Return non-zero for failure. RETURNS int ******************************************************************************/ int vc_interface_init (void) { int status; uint32_t regval; int i, initcount; uint32_t hostportcfg; // Read address of interface area. printk(KERN_INFO "Detecting VC03 VMCS ."); // hostportcfg = HW_VC03_HOSTBUS_CFG00; initcount = 50; regval = 0; // vc_host_init(); regval = vc_host_read32(VC_APP_ADDRESS, 0); regval = vc_host_read32(VC_SHAREDPTR_ADDR, 0); regval = vc_host_read32(VC_APP_ADDRESS, 0); regval = vc_host_read32(VC_SHAREDPTR_ADDR, 0); regval = vc_host_read32(VC_APP_ADDRESS, 0); regval = vc_host_read32(VC_SHAREDPTR_ADDR, 0); while(1) { status = vchost_portinit(&hostportcfg); if(status == 0) { regval = vc_host_read32(VC_APP_ADDRESS, 0); if(regval == 1) { // Read from VC_SHAREDPTR_ADDR - VMCS sets this to 1 printk(" OK VC03 VMCS is running.\n"); break; } else { //printk( "vc_interface_init: read address of intf area failed\n" ); } } if(initcount < 1) { printk( "VC03 driver error: VMCS is not running.\n"); return 1; // VMCS is not running } printk("."); vc03_delay_msec(50); --initcount; } vc_interface_base = vc_host_read32(VC_SHAREDPTR_ADDR, 0); VC_DEBUG(Trace, "vc_interface_base = 0x%08x\n", vc_interface_base ); if ((vc_interface_base == 0) || ((vc_interface_base & 3) != 0)) { printk( KERN_ERR "invalid vc_interface_base: 0x%08X\n", vc_interface_base); return 1; // Sanity check - pointer must be non-null and aligned to a 4-byte address } // Read shared memory header. status = read_header(); if ( status != 0 ) { printk( "vc_interface_init: read_header failed\n" ); return status; } // Probably advisable to have a lock to protect multiple threads trying to // set interface bits at once. We protect reads too, just to be sure another // thread doesn't use half updated values. if (interface_lock == NULL) interface_lock = vc_lock_create(); // Start us off in polling mode. The host can put us into interrupt mode once // they have done enough work to set up and process the interrupts. // (NOTE: I think this now does nothing. DAP.) vc_interface_set_polling(1); // Very hookey hack. Write some bytes into the dummy values after the vin_int_ack // so we can use them to tell if we're doing something valid. { int offset = (uint32_t)&vc_sharedmem_header.vin_int_req - (uint32_t)&vc_sharedmem_header; vc_host_read_consecutive(&vc_sharedmem_header.vin_int_req, vc_interface_base + offset, sizeof(VC_SHAREDMEM_HEADER_T) - offset, 0); memcpy( vc_sharedmem_header.dummy1, testPattern, sizeof( testPattern )); memcpy( vc_sharedmem_header.dummy2, testPattern, sizeof( testPattern )); vc_host_write_consecutive( vc_interface_base + offset, &vc_sharedmem_header.vin_int_req, sizeof(VC_SHAREDMEM_HEADER_T) - offset, 0); } // Do not set this as we get reinitialised after being powered down and up again // and we do not expect services to recreate their events. //num_reg_events = 0; for (i = 0; i < VC_NUM_INTERFACES; i++) { VC_GENERIC_INTERFACE_T intf; char *stypeStr; if ( vc_sharedmem_header.iface[i] == 0 ) { VC_DEBUG( Verbose, "iface[%d] not present\n", i); } else { vc_host_read_consecutive(&intf, vc_interface_base + vc_sharedmem_header.iface[i], sizeof(VC_GENERIC_INTERFACE_T), 0); intf.stype = VC_VTOH16(intf.stype); switch(intf.stype) { case VC_STYPE_GENCMD: stypeStr = "gencmd "; break; case VC_STYPE_DISPMAN: stypeStr = "dispman"; break; case VC_STYPE_TOUCHSCREEN: stypeStr = "touch "; break; case VC_STYPE_DATASERVICE: stypeStr = "dataSvc"; break; case VC_STYPE_FILESERVICE: stypeStr = "fileSvc"; break; case VC_STYPE_HOSTREQ: stypeStr = "hostReq"; break; case VC_STYPE_FRMFWD: stypeStr = "frmfwd "; break; case VC_STYPE_ILCS: stypeStr = "ilcs "; break; case VC_STYPE_OGLESSVC: stypeStr = "ogles "; break; default: stypeStr = "*******"; break; } if ( intf.itype == VC_ITYPE_MSGFIFO ) { VC_MSGFIFO_INTERFACE_T msgFifo; VC_HOST_READ_BYTESWAPPED_16( &msgFifo, vc_interface_base + vc_sharedmem_header.iface[i], sizeof(VC_MSGFIFO_INTERFACE_T), 0); VC_DEBUG( Trace, "iface[%d]: 0x%04x stype:%03d '%s' msgFifo %d bytes (to-vc) %d bytes (from-vc)\n", i, vc_sharedmem_header.iface[i], intf.stype, stypeStr, msgFifo.vin_fmax - msgFifo.vin_fmin - VC_INTERFACE_BLOCK_SIZE, msgFifo.vout_fmax - msgFifo.vout_fmin - VC_INTERFACE_BLOCK_SIZE ); } else { VC_DEBUG( Trace, "iface[%d]: 0x%04x stype:%03d '%s'\n", i, vc_sharedmem_header.iface[i], intf.stype, stypeStr ); } } } return 0; }