コード例 #1
0
int bcm2835_audio_close(bcm2835_alsa_stream_t * alsa_stream)
{
	VC_AUDIO_MSG_T m;
	AUDIO_INSTANCE_T *instance = alsa_stream->instance;
	int32_t success;
	int ret;
	LOG_DBG(" .. IN\n");

	my_workqueue_quit(alsa_stream);

	if(mutex_lock_interruptible(&instance->vchi_mutex))
	{
		LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",instance->num_connections);
		return -EINTR;
	}
	vchi_service_use(instance->vchi_handle[0]);

	m.type = VC_AUDIO_MSG_TYPE_CLOSE;

	/* Create the message available completion */
	init_completion(&instance->msg_avail_comp);

	/* Send the message to the videocore */
	success = vchi_msg_queue(instance->vchi_handle[0],
				 &m, sizeof m,
				 VCHI_FLAGS_BLOCK_UNTIL_QUEUED, NULL);

	if (success != 0) {
		LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n",
			__func__, success);
		ret = -1;
		goto unlock;
	}

	ret = wait_for_completion_interruptible(&instance->msg_avail_comp);
	if (ret) {
		LOG_DBG("%s: failed on waiting for event (status=%d)\n",
			__func__, success);
		goto unlock;
	}
	if (instance->result != 0) {
		LOG_ERR("%s: failed result (status=%d)\n",
			__func__, instance->result);

		ret = -1;
		goto unlock;
	}

	ret = 0;

unlock:
	vchi_service_release(instance->vchi_handle[0]);
	mutex_unlock(&instance->vchi_mutex);

	/* Stop the audio service */
	if (instance) {
		vc_vchi_audio_deinit(instance);
		alsa_stream->instance = NULL;
	}
	LOG_DBG(" .. OUT\n");
	return ret;
}
コード例 #2
0
int bcm2835_audio_write_worker(bcm2835_alsa_stream_t *alsa_stream,
			       uint32_t count, void *src)
{
	VC_AUDIO_MSG_T m;
	AUDIO_INSTANCE_T *instance = alsa_stream->instance;
	int32_t success;
	int ret;

	LOG_DBG(" .. IN\n");

	LOG_INFO(" Writing %d bytes from %p\n", count, src);

	if(mutex_lock_interruptible(&instance->vchi_mutex))
	{
		LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",instance->num_connections);
		return -EINTR;
	}
	vchi_service_use(instance->vchi_handle[0]);

	if ( instance->peer_version==0 && vchi_get_peer_version(instance->vchi_handle[0], &instance->peer_version) == 0 ) {
		LOG_DBG("%s: client version %d connected\n", __func__, instance->peer_version);
	}
	m.type = VC_AUDIO_MSG_TYPE_WRITE;
	m.u.write.count = count;
	// old version uses bulk, new version uses control
	m.u.write.max_packet = instance->peer_version < 2 || force_bulk ? 0:4000;
	m.u.write.callback = alsa_stream->fifo_irq_handler;
	m.u.write.cookie = alsa_stream;
	m.u.write.silence = src == NULL;

	/* Send the message to the videocore */
	success = vchi_msg_queue(instance->vchi_handle[0],
				 &m, sizeof m,
				 VCHI_FLAGS_BLOCK_UNTIL_QUEUED, NULL);

	if (success != 0) {
		LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n",
			__func__, success);

		ret = -1;
		goto unlock;
	}
	if (!m.u.write.silence) {
		if (m.u.write.max_packet == 0) {
			/* Send the message to the videocore */
			success = vchi_bulk_queue_transmit(instance->vchi_handle[0],
							   src, count,
							   0 *
							   VCHI_FLAGS_BLOCK_UNTIL_QUEUED
							   +
							   1 *
							   VCHI_FLAGS_BLOCK_UNTIL_DATA_READ,
							   NULL);
		} else {
			while (count > 0) {
				int bytes = min((int)m.u.write.max_packet, (int)count);
				success = vchi_msg_queue(instance->vchi_handle[0],
							 src, bytes,
							 VCHI_FLAGS_BLOCK_UNTIL_QUEUED, NULL);
				src = (char *)src + bytes;
				count -= bytes;
			}
		}
		if (success != 0) {
			LOG_ERR
			    ("%s: failed on vchi_bulk_queue_transmit (status=%d)\n",
			     __func__, success);

			ret = -1;
			goto unlock;
		}
	}
	ret = 0;

unlock:
	vchi_service_release(instance->vchi_handle[0]);
	mutex_unlock(&instance->vchi_mutex);
	LOG_DBG(" .. OUT\n");
	return ret;
}
コード例 #3
0
static int bcm2835_audio_set_ctls_chan(bcm2835_alsa_stream_t * alsa_stream,
				       bcm2835_chip_t * chip)
{
	VC_AUDIO_MSG_T m;
	AUDIO_INSTANCE_T *instance = alsa_stream->instance;
	int32_t success;
	int ret;
	LOG_DBG(" .. IN\n");

	LOG_INFO
	    (" Setting ALSA dest(%d), volume(%d)\n", chip->dest, chip->volume);

	if(mutex_lock_interruptible(&instance->vchi_mutex))
	{
		LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",instance->num_connections);
		return -EINTR;
	}
	vchi_service_use(instance->vchi_handle[0]);

	instance->result = -1;

	m.type = VC_AUDIO_MSG_TYPE_CONTROL;
	m.u.control.dest = chip->dest;
	m.u.control.volume = chip->volume;

	/* Create the message available completion */
	init_completion(&instance->msg_avail_comp);

	/* Send the message to the videocore */
	success = vchi_msg_queue(instance->vchi_handle[0],
				 &m, sizeof m,
				 VCHI_FLAGS_BLOCK_UNTIL_QUEUED, NULL);

	if (success != 0) {
		LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n",
			__func__, success);

		ret = -1;
		goto unlock;
	}

	/* We are expecting a reply from the videocore */
	ret = wait_for_completion_interruptible(&instance->msg_avail_comp);
	if (ret) {
		LOG_DBG("%s: failed on waiting for event (status=%d)\n",
			__func__, success);
		goto unlock;
	}

	if (instance->result != 0) {
		LOG_ERR("%s: result=%d\n", __func__, instance->result);

		ret = -1;
		goto unlock;
	}

	ret = 0;

unlock:
	vchi_service_release(instance->vchi_handle[0]);
	mutex_unlock(&instance->vchi_mutex);

	LOG_DBG(" .. OUT\n");
	return ret;
}
コード例 #4
0
int bcm2835_audio_set_params(bcm2835_alsa_stream_t * alsa_stream,
			     uint32_t channels, uint32_t samplerate,
			     uint32_t bps)
{
	VC_AUDIO_MSG_T m;
	AUDIO_INSTANCE_T *instance = alsa_stream->instance;
	int32_t success;
	int ret;
	LOG_DBG(" .. IN\n");

	LOG_INFO
	    (" Setting ALSA channels(%d), samplerate(%d), bits-per-sample(%d)\n",
	     channels, samplerate, bps);

	/* resend ctls - alsa_stream may not have been open when first send */
	ret = bcm2835_audio_set_ctls_chan(alsa_stream, alsa_stream->chip);
	if (ret != 0) {
		LOG_ERR(" Alsa controls not supported\n");
		return -EINVAL;
	}

	if(mutex_lock_interruptible(&instance->vchi_mutex))
	{
		LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",instance->num_connections);
		return -EINTR;
	}
	vchi_service_use(instance->vchi_handle[0]);

	instance->result = -1;

	m.type = VC_AUDIO_MSG_TYPE_CONFIG;
	m.u.config.channels = channels;
	m.u.config.samplerate = samplerate;
	m.u.config.bps = bps;

	/* Create the message available completion */
	init_completion(&instance->msg_avail_comp);

	/* Send the message to the videocore */
	success = vchi_msg_queue(instance->vchi_handle[0],
				 &m, sizeof m,
				 VCHI_FLAGS_BLOCK_UNTIL_QUEUED, NULL);

	if (success != 0) {
		LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n",
			__func__, success);

		ret = -1;
		goto unlock;
	}

	/* We are expecting a reply from the videocore */
	ret = wait_for_completion_interruptible(&instance->msg_avail_comp);
	if (ret) {
		LOG_DBG("%s: failed on waiting for event (status=%d)\n",
			__func__, success);
		goto unlock;
	}

	if (instance->result != 0) {
		LOG_ERR("%s: result=%d", __func__, instance->result);

		ret = -1;
		goto unlock;
	}

	ret = 0;

unlock:
	vchi_service_release(instance->vchi_handle[0]);
	mutex_unlock(&instance->vchi_mutex);

	LOG_DBG(" .. OUT\n");
	return ret;
}
コード例 #5
0
ファイル: vc_vchi_fb.c プロジェクト: CVlaspoel/VSMC-i9105p
int32_t vc_vchi_fb_read(VC_VCHI_FB_HANDLE_T handle, uint32_t res_handle,
			void *buf, int32_t size)
{
	int32_t ret, success = 0;
	FB_INSTANCE_T *instance = handle;
	uint32_t msg_len;
	VC_FB_MSG_HDR_T *msg_hdr;
	VC_FB_READ_T *fb_read;
	VC_FB_RESULT_T result;

	if (handle == NULL) {
		LOG_ERR("%s: invalid handle", __func__);

		ret = -1;
		goto out;
	}

	if (buf == NULL) {
		LOG_ERR("%s: invalid buffer pointer", __func__);

		ret = -1;
		goto out;
	}

	if (size <= 0) {
		LOG_ERR("%s: invalid buffer size %d", __func__, size);

		ret = -1;
		goto out;
	}

	mutex_lock(&instance->vchi_mutex);
	vchi_service_use(instance->vchi_handle[0]);

	LOG_INFO("%s: enter", __func__);

	msg_len = sizeof(*msg_hdr) + sizeof(*fb_read);
	memset(instance->msg_buf, 0, msg_len);

	msg_hdr = (VC_FB_MSG_HDR_T *) instance->msg_buf;
	msg_hdr->type = VC_FB_MSG_TYPE_READ;

	fb_read = (VC_FB_READ_T *) msg_hdr->body;
	fb_read->res_handle = res_handle;
	fb_read->size = size;

	/* Send the message to the videocore */
	success = vchi_msg_queue(instance->vchi_handle[0],
				 instance->msg_buf, msg_len,
				 VCHI_FLAGS_BLOCK_UNTIL_QUEUED, NULL);
	if (success != 0) {
		LOG_ERR("%s: failed to queue message (success=%d)",
			__func__, success);

		ret = -1;
		goto unlock;
	}
	LOG_INFO("%s: done sending msg", __func__);
	/* We are expecting a reply from the videocore */
	down(&instance->msg_avail);

	success = vchi_msg_dequeue(instance->vchi_handle[0],
				   &result, sizeof(result),
				   &msg_len, VCHI_FLAGS_NONE);

	LOG_INFO("%s: got reply message %x", __func__, result.success);

	if (success != 0) {
		LOG_ERR("%s: failed to dequeue message (success=%d)",
			__func__, success);

		ret = -1;
		goto unlock;
	} else if (msg_len != sizeof(result)) {
		LOG_ERR("%s: incorrect message length %u (expected=%u)",
			__func__, msg_len, sizeof(result));

		ret = -1;
		goto unlock;
	}

	LOG_INFO("%s: all good do bulk_receive %x", __func__, result.success);
	success = vchi_bulk_queue_receive(instance->vchi_handle[0],
					  buf,
					  size,
					  VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE,
					  0);

	if (success != 0)
		LOG_ERR("%s: vchi_bulk_queue_receive failed", __func__);

unlock:

	vchi_service_release(instance->vchi_handle[0]);
	mutex_unlock(&instance->vchi_mutex);

	ret = success;
	LOG_INFO("%s: exit", __func__);
out:
	return ret;
}
コード例 #6
0
ファイル: vc_vchi_fb.c プロジェクト: CVlaspoel/VSMC-i9105p
int32_t vc_vchi_fb_cfg(VC_VCHI_FB_HANDLE_T handle,
		       VC_FB_CFG_T *cfg, VC_FB_CFG_RESULT_T *cfg_result)
{
	int32_t ret;
	FB_INSTANCE_T *instance = handle;
	int32_t success;
	uint32_t msg_len;
	VC_FB_MSG_HDR_T *msg_hdr;

	if (handle == NULL) {
		LOG_ERR("%s: invalid handle", __func__);

		ret = -1;
		goto out;
	}

	if (cfg == NULL) {
		LOG_ERR("%s: invalid cfg pointer", __func__);

		ret = -1;
		goto out;
	}

	if (cfg_result == NULL) {
		LOG_ERR("%s: invalid cfg_result pointer", __func__);

		ret = -1;
		goto out;
	}

	mutex_lock(&instance->vchi_mutex);
	vchi_service_use(instance->vchi_handle[0]);

	msg_len = sizeof(*msg_hdr) + sizeof(*cfg);
	memset(instance->msg_buf, 0, msg_len);

	msg_hdr = (VC_FB_MSG_HDR_T *) instance->msg_buf;
	msg_hdr->type = VC_FB_MSG_TYPE_CFG;

	/* Copy the user buffer into the message buffer */
	memcpy(msg_hdr->body, cfg, sizeof(*cfg));

	/* Send the message to the videocore */
	success = vchi_msg_queue(instance->vchi_handle[0],
				 instance->msg_buf, msg_len,
				 VCHI_FLAGS_BLOCK_UNTIL_QUEUED, NULL);
	if (success != 0) {
		LOG_ERR("%s: failed to queue message (success=%d)",
			__func__, success);

		ret = -1;
		goto unlock;
	}
	/* We are expecting a reply from the videocore */
	down(&instance->msg_avail);

	success = vchi_msg_dequeue(instance->vchi_handle[0],
				   cfg_result, sizeof(*cfg_result),
				   &msg_len, VCHI_FLAGS_NONE);
	if (success != 0) {
		LOG_ERR("%s: failed to dequeue message (success=%d)",
			__func__, success);

		ret = -1;
		goto unlock;
	} else if (msg_len != sizeof(*cfg_result)) {
		LOG_ERR("%s: incorrect message length %u (expected=%u)",
			__func__, msg_len, sizeof(*cfg_result));

		ret = -1;
		goto unlock;
	}

	ret = cfg_result->success ? -1 : 0;

unlock:
	vchi_service_release(instance->vchi_handle[0]);
	mutex_unlock(&instance->vchi_mutex);

out:
	return ret;
}
コード例 #7
0
ファイル: vc_vchi_fb.c プロジェクト: CVlaspoel/VSMC-i9105p
int32_t vc_vchi_fb_swap(VC_VCHI_FB_HANDLE_T handle,
			uint32_t res_handle, uint32_t active_frame)
{
	int ret;
	FB_INSTANCE_T *instance = handle;
	int32_t success;
	uint32_t msg_len;
	VC_FB_MSG_HDR_T *msg_hdr;
	VC_FB_SWAP_T *swap;
	VC_FB_RESULT_T result;

	if (handle == NULL) {
		LOG_ERR("%s: invalid handle %p", __func__, handle);

		return -1;
	}

	mutex_lock(&instance->vchi_mutex);
	vchi_service_use(instance->vchi_handle[0]);

	msg_len = sizeof(*msg_hdr) + sizeof(*swap);
	memset(instance->msg_buf, 0, msg_len);

	msg_hdr = (VC_FB_MSG_HDR_T *) instance->msg_buf;
	msg_hdr->type = VC_FB_MSG_TYPE_SWAP;

	swap = (VC_FB_SWAP_T *) msg_hdr->body;
	swap->res_handle = res_handle;
	swap->active_frame = active_frame;

	/* Send the message to the videocore */
	success = vchi_msg_queue(instance->vchi_handle[0],
				 instance->msg_buf, msg_len,
				 VCHI_FLAGS_BLOCK_UNTIL_QUEUED, NULL);
	if (success != 0) {
		LOG_ERR("%s: failed to queue message (success=%d)",
			__func__, success);

		ret = -1;
		goto unlock;
	}
	/* We are expecting a reply from the videocore */
	down(&instance->msg_avail);

	success = vchi_msg_dequeue(instance->vchi_handle[0],
				   &result, sizeof(result),
				   &msg_len, VCHI_FLAGS_NONE);
	if (success != 0) {
		LOG_ERR("%s: failed to dequeue message (success=%d)",
			__func__, success);

		ret = -1;
		goto unlock;
	} else if (msg_len != sizeof(result)) {
		LOG_ERR("%s: incorrect message length %u (expected=%u)",
			__func__, msg_len, sizeof(result));

		ret = -1;
		goto unlock;
	}

	ret = result.success ? -1 : 0;

unlock:
	vchi_service_release(instance->vchi_handle[0]);
	mutex_unlock(&instance->vchi_mutex);

	return ret;
}
コード例 #8
0
ファイル: vc_vchi_fb.c プロジェクト: CVlaspoel/VSMC-i9105p
int32_t vc_vchi_fb_alloc(VC_VCHI_FB_HANDLE_T handle,
			 VC_FB_ALLOC_T *alloc,
			 VC_FB_ALLOC_RESULT_T *alloc_result)
{
	FB_INSTANCE_T *instance = handle;
	int32_t success;
	uint32_t msg_len;
	VC_FB_MSG_HDR_T *msg_hdr;
	int32_t ret = -1;

	if (handle == NULL) {
		LOG_ERR("%s: invalid handle %p", __func__, handle);

		return -1;
	}

	if (alloc == NULL) {
		LOG_ERR("%s: invalid alloc pointer %p", __func__, alloc);

		return -1;
	}
	/* TODO check individual alloc member values */

	if (alloc_result == NULL) {
		LOG_ERR("%s: invalid alloc_result pointer 0x%p", __func__,
			alloc_result);

		return -1;
	}

	mutex_lock(&instance->vchi_mutex);
	vchi_service_use(instance->vchi_handle[0]);

	msg_len = sizeof(*msg_hdr) + sizeof(*alloc);
	memset(instance->msg_buf, 0, msg_len);

	msg_hdr = (VC_FB_MSG_HDR_T *) instance->msg_buf;
	msg_hdr->type = VC_FB_MSG_TYPE_ALLOC;

	/* Copy the user buffer into the message buffer */
	memcpy(msg_hdr->body, alloc, sizeof(*alloc));

	/* Send the message to the videocore */
	success = vchi_msg_queue(instance->vchi_handle[0],
				 instance->msg_buf, msg_len,
				 VCHI_FLAGS_BLOCK_UNTIL_QUEUED, NULL);
	if (success != 0) {
		LOG_ERR("%s: failed to queue message (success=%d)",
			__func__, success);

		goto unlock;
	}
	/*  We are expecting a reply from the videocore */
	down(&instance->msg_avail);

	success = vchi_msg_dequeue(instance->vchi_handle[0],
				   alloc_result, sizeof(*alloc_result),
				   &msg_len, VCHI_FLAGS_NONE);
	if (success != 0) {
		LOG_ERR("%s: failed to dequeue message (success=%d)",
			__func__, success);

		goto unlock;
	} else if (msg_len != sizeof(*alloc_result)) {
		LOG_ERR("%s: incorrect message length %u (expected=%u)",
			__func__, msg_len, sizeof(*alloc_result));

		goto unlock;
	}
	/* success if we got to here */
	ret = 0;

unlock:
	vchi_service_release(instance->vchi_handle[0]);
	mutex_unlock(&instance->vchi_mutex);

	return ret;
}
コード例 #9
0
ファイル: vc_vchi_fb.c プロジェクト: CVlaspoel/VSMC-i9105p
int32_t vc_vchi_fb_get_scrn_info(VC_VCHI_FB_HANDLE_T handle,
				 VC_FB_SCRN scrn, VC_FB_SCRN_INFO_T *info)
{
	int ret;
	FB_INSTANCE_T *instance = handle;
	int32_t success;
	uint32_t msg_len;
	VC_FB_MSG_HDR_T *msg_hdr;
	VC_FB_GET_SCRN_INFO_T *get_scrn_info;

	if (handle == NULL) {
		LOG_ERR("%s: invalid handle %p", __func__, handle);

		return -1;
	}

	if (scrn >= VC_FB_SCRN_MAX) {
		LOG_ERR("%s: invalid screen %u", __func__, scrn);

		return -1;
	}

	if (info == NULL) {
		LOG_ERR("%s: invalid info pointer %p", __func__, info);

		return -1;
	}

	mutex_lock(&instance->vchi_mutex);
	vchi_service_use(instance->vchi_handle[0]);

	msg_len = sizeof(*msg_hdr) + sizeof(*get_scrn_info);
	memset(instance->msg_buf, 0, msg_len);

	msg_hdr = (VC_FB_MSG_HDR_T *) instance->msg_buf;
	msg_hdr->type = VC_FB_MSG_TYPE_GET_SCRN_INFO;

	get_scrn_info = (VC_FB_GET_SCRN_INFO_T *) msg_hdr->body;
	get_scrn_info->scrn = scrn;

	/* Send the message to the videocore */
	success = vchi_msg_queue(instance->vchi_handle[0],
				 instance->msg_buf, msg_len,
				 VCHI_FLAGS_BLOCK_UNTIL_QUEUED, NULL);
	if (success != 0) {
		LOG_ERR("%s: failed to queue message (success=%d)",
			__func__, success);

		ret = -1;
		goto unlock;
	}
	/* We are expecting a reply from the videocore */
	down(&instance->msg_avail);

	success = vchi_msg_dequeue(instance->vchi_handle[0],
				   info, sizeof(*info),
				   &msg_len, VCHI_FLAGS_NONE);
	if (success != 0) {
		LOG_ERR("%s: failed to dequeue message (success=%d)",
			__func__, success);

		ret = -1;
		goto unlock;
	} else if (msg_len != sizeof(*info)) {
		LOG_ERR("%s: incorrect message length %u (expected=%u)",
			__func__, msg_len, sizeof(*info));

		ret = -1;
		goto unlock;
	}

	ret = 0;

unlock:
	vchi_service_release(instance->vchi_handle[0]);
	mutex_unlock(&instance->vchi_mutex);

	return ret;
}