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