Beispiel #1
0
/*
 * sst_get_stream - this function prepares for stream allocation
 *
 * @str_param : stream param
 */
int sst_get_stream(struct intel_sst_drv *ctx,
			struct snd_sst_params *str_param)
{
	int retval;
	struct stream_info *str_info;

	/* stream is not allocated, we are allocating */
	retval = ctx->ops->alloc_stream(ctx, str_param);
	if (retval <= 0) {
		return -EIO;
	}
	/* store sampling freq */
	str_info = &ctx->streams[retval];
	str_info->sfreq = sst_get_sfreq(str_param);

	return retval;
}
Beispiel #2
0
int sst_alloc_stream_mfld(char *params)
{
	struct ipc_post *msg = NULL;
	struct snd_sst_alloc_params_mfld alloc_param;
	struct snd_sst_params *str_params;
	struct stream_info *str_info;
	unsigned int stream_ops, device;
	struct snd_sst_stream_params_mfld *sparams;
	unsigned int pcm_slot = 0, num_ch, pcm_wd_sz, sfreq;
	int str_id;
	u8 codec;
	u32 rb_size, rb_addr, period_count;
	unsigned long irq_flags;

	pr_debug("In %s\n", __func__);

	BUG_ON(!params);
	str_params = (struct snd_sst_params *)params;
	stream_ops = str_params->ops;
	codec = str_params->codec;
	device = str_params->device_type;
	num_ch = sst_get_num_channel(str_params);
	sfreq = sst_get_sfreq(str_params);
	pcm_wd_sz = sst_get_wdsize(str_params);
	rb_size = str_params->aparams.ring_buf_info[0].size;
	rb_addr = str_params->aparams.ring_buf_info[0].addr;
	period_count = str_params->aparams.frag_size / 4;


	pr_debug("period_size = %d\n", period_count);
	pr_debug("ring_buf_addr = 0x%x\n", rb_addr);
	pr_debug("ring_buf_size = %d\n", rb_size);
	pr_debug("device_type=%d\n", device);
	pr_debug("sfreq =%d\n", sfreq);
	pr_debug("stream_ops%d codec%d device%d\n", stream_ops, codec, device);


	sparams = kzalloc(sizeof(*sparams), GFP_KERNEL);
	if (!sparams) {
		pr_err("Unable to allocate snd_sst_stream_params\n");
		return -ENOMEM;
	}


	sparams->uc.pcm_params.codec = codec;
	sparams->uc.pcm_params.num_chan = num_ch;
	sparams->uc.pcm_params.pcm_wd_sz = pcm_wd_sz;
	sparams->uc.pcm_params.reserved = 0;
	sparams->uc.pcm_params.sfreq = sfreq;
	sparams->uc.pcm_params.ring_buffer_size = rb_size;
	sparams->uc.pcm_params.period_count = period_count;
	sparams->uc.pcm_params.ring_buffer_addr = rb_addr;



	if (sst_check_device_type(device, num_ch, &pcm_slot)) {
		kfree(sparams);
		return -EINVAL;
	}
	mutex_lock(&sst_drv_ctx->stream_lock);
	str_id = device;
	mutex_unlock(&sst_drv_ctx->stream_lock);
	pr_debug("slot %x\n", pcm_slot);

	/*allocate device type context*/
	sst_init_stream(&sst_drv_ctx->streams[str_id], codec,
			str_id, stream_ops, pcm_slot);
	/* send msg to FW to allocate a stream */
	if (sst_create_large_msg(&msg)) {
		kfree(sparams);
		return -ENOMEM;
	}

	alloc_param.str_type.codec_type = codec;
	alloc_param.str_type.str_type = SST_STREAM_TYPE_MUSIC;
	alloc_param.str_type.operation = stream_ops;
	alloc_param.str_type.protected_str = 0; /* non drm */
	alloc_param.str_type.time_slots = pcm_slot;
	alloc_param.str_type.reserved = 0;
	alloc_param.str_type.result = 0;

	sst_fill_header(&msg->header, IPC_IA_ALLOC_STREAM, 1, str_id);
	msg->header.part.data = sizeof(alloc_param) + sizeof(u32);
	memcpy(&alloc_param.stream_params, sparams,
			sizeof(*sparams));
	kfree(sparams);

	memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
	memcpy(msg->mailbox_data + sizeof(u32), &alloc_param,
			sizeof(alloc_param));
	str_info = &sst_drv_ctx->streams[str_id];
	str_info->ctrl_blk.condition = false;
	str_info->ctrl_blk.ret_code = 0;
	str_info->ctrl_blk.on = true;
	spin_lock_irqsave(&sst_drv_ctx->ipc_spin_lock, irq_flags);
	list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
	spin_unlock_irqrestore(&sst_drv_ctx->ipc_spin_lock, irq_flags);
	sst_drv_ctx->ops->post_message(&sst_drv_ctx->ipc_post_msg_wq);
	pr_debug("SST DBG:alloc stream done\n");
	return str_id;
}
Beispiel #3
0
/*
 * sst_get_stream - this function prepares for stream allocation
 *
 * @str_param : stream param
 */
int sst_get_stream(struct snd_sst_params *str_param)
{
	int i, retval;
	struct stream_info *str_info;
	struct snd_sst_lib_download *lib_dnld;

	/* stream is not allocated, we are allocating */
	retval = sst_get_stream_allocated(str_param, &lib_dnld);
	if (retval == -(SST_LIB_ERR_LIB_DNLD_REQUIRED)) {
		/* codec download is required */
		struct snd_sst_alloc_response *response;

		pr_debug("Codec is required.... trying that\n");
		if (lib_dnld == NULL) {
			pr_err("lib download null!!! abort\n");
			return -EIO;
		}
		i = sst_get_block_stream(sst_drv_ctx);
		response = sst_drv_ctx->alloc_block[i].ops_block.data;
		pr_debug("alloc block allocated = %d\n", i);
		if (i < 0) {
			kfree(lib_dnld);
			return -ENOMEM;
		}
		retval = sst_load_library(lib_dnld, str_param->ops);
		kfree(lib_dnld);

		sst_drv_ctx->alloc_block[i].sst_id = BLOCK_UNINIT;
		if (!retval) {
			pr_debug("codec was downloaded successfully\n");

			retval = sst_get_stream_allocated(str_param, &lib_dnld);
			if (retval <= 0)
				goto err;

			pr_debug("Alloc done stream id %d\n", retval);
		} else {
			pr_debug("codec download failed\n");
			retval = -EIO;
			goto err;
		}
	} else if  (retval <= 0)
		goto err;
	/*else
		set_port_params(str_param, str_param->ops);*/

	/* store sampling freq */
	str_info = &sst_drv_ctx->streams[retval];
	str_info->sfreq = sst_get_sfreq(str_param);

	/* power on the analog, if reqd */
	if (str_param->ops == STREAM_OPS_PLAYBACK ||
			str_param->ops == STREAM_OPS_PLAYBACK_DRM) {
		if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID)
			sst_drv_ctx->scard_ops->power_up_pmic_pb(
					sst_drv_ctx->pmic_port_instance);
		else
			sst_drv_ctx->scard_ops->power_up_pmic_pb(
							str_info->device);
		/*Only if the playback is MP3 - Send a message*/
		sst_drv_ctx->pb_streams++;
	} else if (str_param->ops == STREAM_OPS_CAPTURE) {

		sst_drv_ctx->scard_ops->power_up_pmic_cp(
				sst_drv_ctx->pmic_port_instance);
		/*Send a messageif not sent already*/
		sst_drv_ctx->cp_streams++;
	}

err:
	return retval;
}