void vc_vchi_gencmd_init (VCHI_INSTANCE_T initialise_instance, VCHI_CONNECTION_T **connections, uint32_t num_connections ) { int32_t success; int i; // record the number of connections memset( &gencmd_client, 0, sizeof(GENCMD_SERVICE_T) ); gencmd_client.num_connections = (int) num_connections; success = os_semaphore_create( &gencmd_client.sema, OS_SEMAPHORE_TYPE_SUSPEND ); assert( success == 0 ); success = os_semaphore_create( &gencmd_message_available_semaphore, OS_SEMAPHORE_TYPE_BUSY_WAIT ); assert( success == 0 ); success = os_semaphore_obtain( &gencmd_message_available_semaphore ); assert( success == 0 ); for (i=0; i<gencmd_client.num_connections; i++) { // Create a 'LONG' service on the each of the connections SERVICE_CREATION_T gencmd_parameters = { MAKE_FOURCC("GCMD"), // 4cc service code connections[i], // passed in fn ptrs 0, // tx fifo size (unused) 0, // tx fifo size (unused) &gencmd_callback, // service callback &gencmd_message_available_semaphore, // callback parameter VC_FALSE, // want_unaligned_bulk_rx VC_FALSE, // want_unaligned_bulk_tx VC_FALSE // want_crc }; success = vchi_service_open( initialise_instance, &gencmd_parameters, &gencmd_client.open_handle[i] ); assert( success == 0 ); } }
/* ---------------------------------------------------------------------- * initialise host-side OpenMAX IL component service * -------------------------------------------------------------------- */ void vc_vchi_ilcs_init( VCHI_INSTANCE_T initialise_instance, VCHI_CONNECTION_T **connections, uint32_t num_connections ) { int32_t success; SERVICE_CREATION_T parameters = { MAKE_FOURCC("ILCS"), // 4cc service code connections[0], // passed in fn ptrs 0, // tx fifo size (unused) 0, // tx fifo size (unused) 0, // service callback 0 }; // callback parameter memset( &vc_ilcsg, 0, sizeof(VC_ILCS_GLOBALS_T) ); // create thread semaphore for blocking os_semaphore_create( &vc_ilcsg.component_lock, OS_SEMAPHORE_TYPE_SUSPEND ); // create semaphore for protecting wait/xid structures os_semaphore_create( &vc_ilcsg.wait_sem, OS_SEMAPHORE_TYPE_SUSPEND ); // create semaphore for correct ordering of control+bulk pairs os_semaphore_create( &vc_ilcsg.send_sem, OS_SEMAPHORE_TYPE_SUSPEND ); // open 'ILCS' service success = vchi_service_open( initialise_instance, ¶meters, &vc_ilcsg.vchi_handle ); vc_assert( success == 0 ); success = os_thread_start( &vc_ilcsg.thread, vc_ilcs_task, NULL, 4000, "ILCS_HOST" ); vc_assert( success == 0 ); }
void vc_vchi_gencmd_init (VCHI_INSTANCE_T initialise_instance, VCHI_CONNECTION_T **connections, uint32_t num_connections ) { VCOS_STATUS_T status; int32_t success; int i; if (gencmd_client.initialised) return; // record the number of connections memset( &gencmd_client, 0, sizeof(GENCMD_SERVICE_T) ); gencmd_client.num_connections = (int) num_connections; status = vcos_mutex_create(&gencmd_client.lock, "HGencmd"); vcos_assert(status == VCOS_SUCCESS); status = vcos_event_create(&gencmd_client.message_available_event, "HGencmd"); vcos_assert(status == VCOS_SUCCESS); for (i=0; i<gencmd_client.num_connections; i++) { // Create a 'LONG' service on the each of the connections SERVICE_CREATION_T gencmd_parameters = { VCHI_VERSION(VC_GENCMD_VER), MAKE_FOURCC("GCMD"), // 4cc service code connections[i], // passed in fn ptrs 0, // tx fifo size (unused) 0, // tx fifo size (unused) &gencmd_callback, // service callback &gencmd_client.message_available_event, // callback parameter VC_FALSE, // want_unaligned_bulk_rx VC_FALSE, // want_unaligned_bulk_tx VC_FALSE // want_crc }; success = vchi_service_open( initialise_instance, &gencmd_parameters, &gencmd_client.open_handle[i] ); assert( success == 0 ); } gencmd_client.initialised = 1; release_gencmd_service(); }
/* VCHIQ stuff */ static void bcm2835_audio_init(struct bcm2835_audio_info *sc) { int status; /* Initialize and create a VCHI connection */ status = vchi_initialise(&sc->vchi_instance); if (status != 0) { printf("vchi_initialise failed: %d\n", status); return; } status = vchi_connect(NULL, 0, sc->vchi_instance); if (status != 0) { printf("vchi_connect failed: %d\n", status); return; } SERVICE_CREATION_T params = { VCHI_VERSION_EX(VC_AUDIOSERV_VER, VC_AUDIOSERV_MIN_VER), VC_AUDIO_SERVER_NAME, /* 4cc service code */ sc->vchi_connection, /* passed in fn pointers */ 0, /* rx fifo size */ 0, /* tx fifo size */ bcm2835_audio_callback, /* service callback */ sc, /* service callback parameter */ 1, 1, 0 /* want crc check on bulk transfers */ }; status = vchi_service_open(sc->vchi_instance, ¶ms, &sc->vchi_handle); if (status == 0) /* Finished with the service for now */ vchi_service_release(sc->vchi_handle); else sc->vchi_handle = VCHIQ_SERVICE_HANDLE_INVALID; }
/* ---------------------------------------------------------------------- * initialise host-side OpenMAX IL component service * -------------------------------------------------------------------- */ void vc_vchi_ilcs_init( VCHI_INSTANCE_T initialise_instance, VCHI_CONNECTION_T **connections, uint32_t num_connections ) { int32_t success; memset( &vc_ilcsg, 0, sizeof(VC_ILCS_GLOBALS_T) ); // sema_init(&vc_ilcsg.msg_prod, 0); sema_init(&vc_ilcsg.msg_cons, 1); sema_init(&vc_ilcsg.omxlog_lock, 1); vc_ilcsg.omxlog_rindex = 0; vc_ilcsg.omxlog_windex = 0; vc_ilcsg.omxlog = vmalloc(VC03_OMXLOG_MAX); memset(vc_ilcsg.omxlog, 0, VC03_OMXLOG_MAX); // create thread semaphore for blocking os_semaphore_create( &vc_ilcsg.component_lock, OS_SEMAPHORE_TYPE_SUSPEND ); os_semaphore_create( &vc_ilcsg.rxmsg_sem, OS_SEMAPHORE_TYPE_SUSPEND ); os_semaphore_obtain( &vc_ilcsg.rxmsg_sem ); // create semaphore for protecting wait/xid structures os_semaphore_create( &vc_ilcsg.wait_sem, OS_SEMAPHORE_TYPE_SUSPEND ); // open 'ILCS' service SERVICE_CREATION_T parameters = { MAKE_FOURCC("ILCS"), // 4cc service code connections[0], // passed in fn ptrs 0, // tx fifo size (unused) 0, // tx fifo size (unused) &vc_ilcs_callback, // service callback &vc_ilcsg.rxmsg_sem }; // callback parameter success = vchi_service_open( initialise_instance, ¶meters, &vc_ilcsg.vchi_handle ); assert( success == 0 ); success = os_thread_start( &vc_ilcsg.thread, vc_ilcs_task, NULL, 4000, "ILCS_HOST" ); assert( success == 0 ); }
void vc_vchi_hostreq_init (VCHI_INSTANCE_T initialise_instance, VCHI_CONNECTION_T **connections, uint32_t num_connections ) { int success, i; // record the number of connections memset( &hostreq_client, 0, sizeof(HOSTREQ_SERVICE_T) ); hostreq_client.num_connections = num_connections; success = os_semaphore_create( &hostreq_client.sema, OS_SEMAPHORE_TYPE_SUSPEND ); assert( success == 0 ); success = os_semaphore_create( &hostreq_client_message_available, OS_SEMAPHORE_TYPE_BUSY_WAIT ); assert( success == 0 ); success = os_semaphore_obtain(&hostreq_client_message_available); assert( success == 0 ); for (i=0; i<hostreq_client.num_connections; i++) { // Create a 'Client' service on the each of the connections SERVICE_CREATION_T hostreq_parameters = { HOSTREQ_NAME, // 4cc service code connections[i], // passed in fn ptrs 0, // tx fifo size (unused) 0, // tx fifo size (unused) &hostreq_client_callback, // service callback &hostreq_client_message_available }; // callback parameter success = vchi_service_open( initialise_instance, &hostreq_parameters, &hostreq_client.client_handle[i] ); assert( success == 0 ); } success = os_thread_start(&hostreq_client_task, &hostreqclient_func, NULL, 2048, "HOSTREQ task"); assert(!success); if(!success) { hostreq_client.initialised = 1; //Send a time across immediately time_t dummytime = 0; //We need to get the real time on a real host success = hostreq_send_command(VC_HOSTREQ_TIME, &dummytime, sizeof(dummytime)); assert( success == 0 ); } }
void vc_vchi_dispmanx_init (VCHI_INSTANCE_T initialise_instance, VCHI_CONNECTION_T **connections, uint32_t num_connections ) { VCOS_STATUS_T status; int32_t success; uint32_t i; // record the number of connections memset( &dispmanx_client, 0, sizeof(DISPMANX_SERVICE_T) ); dispmanx_client.num_connections = num_connections; status = vcos_mutex_create(&dispmanx_client.lock, "HDispmanx"); vcos_assert(status == VCOS_SUCCESS); status = vcos_event_create(&dispmanx_message_available_event, "HDispmanx"); vcos_assert(status == VCOS_SUCCESS); status = vcos_event_create(&dispmanx_notify_available_event, "HDispmanx"); vcos_assert(status == VCOS_SUCCESS); dispmanx_client.initialised = 1; for (i=0; i<dispmanx_client.num_connections; i++) { VCOS_THREAD_ATTR_T attrs; // Create a 'Client' service on the each of the connections SERVICE_CREATION_T dispmanx_parameters = { DISPMANX_CLIENT_NAME, // 4cc service code connections[i], // passed in fn ptrs 0, // tx fifo size (unused) 0, // tx fifo size (unused) &dispmanx_client_callback, // service callback &dispmanx_message_available_event, // callback parameter VC_FALSE, // want_unaligned_bulk_rx VC_FALSE, // want_unaligned_bulk_tx VC_FALSE, // want_crc }; SERVICE_CREATION_T dispmanx_parameters2 = { DISPMANX_NOTIFY_NAME, // 4cc service code connections[i], // passed in fn ptrs 0, // tx fifo size (unused) 0, // tx fifo size (unused) &dispmanx_notify_callback, // service callback &dispmanx_notify_available_event, // callback parameter VC_FALSE, // want_unaligned_bulk_rx VC_FALSE, // want_unaligned_bulk_tx VC_FALSE, // want_crc }; success = vchi_service_open( initialise_instance, &dispmanx_parameters, &dispmanx_client.client_handle[i] ); vcos_assert( success == 0 ); // Create the async service of dispman to handle update callback success = vchi_service_open( initialise_instance, &dispmanx_parameters2, &dispmanx_client.notify_handle[i] ); vcos_assert( success == 0 ); //Create the notifier task vcos_thread_attr_init(&attrs); vcos_thread_attr_setstacksize(&attrs, 2048); vcos_thread_attr_settimeslice(&attrs, 1); status = vcos_thread_create(&dispmanx_notify_task, "HDispmanx Notify", &attrs, dispmanx_notify_func, NULL); vcos_assert(status == VCOS_SUCCESS); // release services until they're actually used vchi_service_release(dispmanx_client.client_handle[i]); vchi_service_release(dispmanx_client.notify_handle[i]); } }
VC_VCHI_FB_HANDLE_T vc_vchi_fb_init(VCHI_INSTANCE_T vchi_instance, VCHI_CONNECTION_T ** vchi_connections, uint32_t num_connections) { uint32_t i; FB_INSTANCE_T *instance; int32_t status; LOG_DBG("%s: start", __func__); if (num_connections > VCHI_MAX_NUM_CONNECTIONS) { LOG_ERR("%s: unsupported number of connections %u (max=%u)", __func__, num_connections, VCHI_MAX_NUM_CONNECTIONS); return NULL; } /* Allocate memory for this instance */ instance = kzalloc(sizeof(*instance), GFP_KERNEL); memset(instance, 0, sizeof(*instance)); instance->num_connections = num_connections; /* Create the message available semaphore */ sema_init(&instance->msg_avail, 0); /* Create a lock for exclusive, serialized VCHI connection access */ mutex_init(&instance->vchi_mutex); /* Open the VCHI service connections */ for (i = 0; i < num_connections; i++) { SERVICE_CREATION_T params = { VCHI_VERSION_EX(VC_FB_VER, VC_FB_VER_MIN), VC_FB_SERVER_NAME, vchi_connections[i], 0, 0, fb_vchi_callback, instance, 0, 0, 0 }; status = vchi_service_open(vchi_instance, ¶ms, &instance->vchi_handle[i]); if (status) { LOG_ERR ("%s: failed to open VCHI service (%d)", __func__, status); goto err_close_services; } /* Finished with the service for now */ vchi_service_release(instance->vchi_handle[i]); } return instance; err_close_services: for (i = 0; i < instance->num_connections; i++) vchi_service_close(instance->vchi_handle[i]); kfree(instance); return NULL; }
static AUDIO_INSTANCE_T *vc_vchi_audio_init(VCHI_INSTANCE_T vchi_instance, VCHI_CONNECTION_T ** vchi_connections, uint32_t num_connections) { uint32_t i; AUDIO_INSTANCE_T *instance; int status; LOG_DBG("%s: start", __func__); if (num_connections > VCHI_MAX_NUM_CONNECTIONS) { LOG_ERR("%s: unsupported number of connections %u (max=%u)\n", __func__, num_connections, VCHI_MAX_NUM_CONNECTIONS); return NULL; } /* Allocate memory for this instance */ instance = kmalloc(sizeof(*instance), GFP_KERNEL); if (!instance) return NULL; memset(instance, 0, sizeof(*instance)); instance->num_connections = num_connections; /* Create a lock for exclusive, serialized VCHI connection access */ mutex_init(&instance->vchi_mutex); /* Open the VCHI service connections */ for (i = 0; i < num_connections; i++) { SERVICE_CREATION_T params = { VCHI_VERSION_EX(VC_AUDIOSERV_VER, VC_AUDIOSERV_MIN_VER), VC_AUDIO_SERVER_NAME, // 4cc service code vchi_connections[i], // passed in fn pointers 0, // rx fifo size (unused) 0, // tx fifo size (unused) audio_vchi_callback, // service callback instance, // service callback parameter 1, //TODO: remove VCOS_FALSE, // unaligned bulk recieves 1, //TODO: remove VCOS_FALSE, // unaligned bulk transmits 0 // want crc check on bulk transfers }; LOG_DBG("%s: about to open %i\n", __func__, i); status = vchi_service_open(vchi_instance, ¶ms, &instance->vchi_handle[i]); LOG_DBG("%s: opened %i: %p=%d\n", __func__, i, instance->vchi_handle[i], status); if (status) { LOG_ERR ("%s: failed to open VCHI service connection (status=%d)\n", __func__, status); goto err_close_services; } /* Finished with the service for now */ vchi_service_release(instance->vchi_handle[i]); } LOG_DBG("%s: okay\n", __func__); return instance; err_close_services: for (i = 0; i < instance->num_connections; i++) { LOG_ERR("%s: closing %i: %p\n", __func__, i, instance->vchi_handle[i]); if (instance->vchi_handle[i]) vchi_service_close(instance->vchi_handle[i]); } kfree(instance); LOG_ERR("%s: error\n", __func__); return NULL; }
/****************************************************************************** NAME vc_vchi_cec_init SYNOPSIS void vc_vchi_cec_init(VCHI_INSTANCE_T initialise_instance, VCHI_CONNECTION_T **connections, uint32_t num_connections ) FUNCTION Initialise the CEC service for use. A negative return value indicates failure (which may mean it has not been started on VideoCore). RETURNS int ******************************************************************************/ VCHPRE_ void VCHPOST_ vc_vchi_cec_init(VCHI_INSTANCE_T initialise_instance, VCHI_CONNECTION_T **connections, uint32_t num_connections ) { int32_t success = -1; uint32_t i; // record the number of connections memset( &cecservice_client, 0, sizeof(CECSERVICE_HOST_STATE_T) ); cecservice_client.num_connections = num_connections; success = os_semaphore_create( &cecservice_client.sema, OS_SEMAPHORE_TYPE_SUSPEND ); vcos_assert( success == 0 ); success = os_semaphore_create( &cecservice_message_available_semaphore, OS_SEMAPHORE_TYPE_BUSY_WAIT ); vcos_assert( success == 0 ); success = os_semaphore_obtain( &cecservice_message_available_semaphore ); vcos_assert( success == 0 ); success = os_semaphore_create( &cecservice_notify_available_semaphore, OS_SEMAPHORE_TYPE_SUSPEND ); vcos_assert( success == 0 ); success = os_semaphore_obtain( &cecservice_notify_available_semaphore ); vcos_assert( success == 0 ); cecservice_client.topology = os_malloc(sizeof(VC_CEC_TOPOLOGY_T), 16, "CEC topology"); vcos_assert(cecservice_client.topology); for (i=0; i < cecservice_client.num_connections; i++) { // Create a 'Client' service on the each of the connections SERVICE_CREATION_T cecservice_parameters = { CECSERVICE_CLIENT_NAME, // 4cc service code connections[i], // passed in fn ptrs 0, // tx fifo size (unused) 0, // tx fifo size (unused) &cecservice_client_callback,// service callback &cecservice_message_available_semaphore, // callback parameter VC_FALSE, // want_unaligned_bulk_rx VC_FALSE, // want_unaligned_bulk_tx VC_FALSE, // want_crc }; SERVICE_CREATION_T cecservice_parameters2 = { CECSERVICE_NOTIFY_NAME, // 4cc service code connections[i], // passed in fn ptrs 0, // tx fifo size (unused) 0, // tx fifo size (unused) &cecservice_notify_callback,// service callback &cecservice_notify_available_semaphore, // callback parameter VC_FALSE, // want_unaligned_bulk_rx VC_FALSE, // want_unaligned_bulk_tx VC_FALSE, // want_crc }; //Create the client to normal CEC service success = vchi_service_open( initialise_instance, &cecservice_parameters, &cecservice_client.client_handle[i] ); vcos_assert( success == 0 ); //Create the client to the async CEC service (any CEC related notifications) success = vchi_service_open( initialise_instance, &cecservice_parameters2, &cecservice_client.notify_handle[i] ); vcos_assert( success == 0 ); } //Create the notifier task success = os_thread_start(&cecservice_notify_task, cecservice_notify_func, &cecservice_client, 2048, "CEC Notify"); vcos_assert( success == 0 ); cecservice_client.initialised = 1; }