/* 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; }
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; }