void sst_process_mad_ops(struct work_struct *work)
{

	struct mad_ops_wq *mad_ops =
			container_of(work, struct mad_ops_wq, wq);
	int retval = 0;

	switch (mad_ops->control_op) {
	case SST_SND_PAUSE:
		retval = sst_pause_stream(mad_ops->stream_id);
		break;
	case SST_SND_RESUME:
		retval = sst_resume_stream(mad_ops->stream_id);
		break;
	case SST_SND_DROP:
		retval = sst_drop_stream(mad_ops->stream_id);
		break;
	case SST_SND_START:
			pr_debug("SST Debug: start stream\n");
		retval = sst_start_stream(mad_ops->stream_id);
		break;
	case SST_SND_STREAM_PROCESS:
		pr_debug("play/capt frames...\n");
		break;
	default:
		pr_err(" wrong control_ops reported\n");
	}
	return;
}
Exemple #2
0
static int sst_stream_drop(struct device *dev, int str_id)
{
	struct stream_info *str_info;
	struct intel_sst_drv *ctx = dev_get_drvdata(dev);

	if (ctx->sst_state != SST_FW_RUNNING)
		return 0;

	str_info = get_stream_info(ctx, str_id);
	if (!str_info)
		return -EINVAL;
	str_info->prev = STREAM_UN_INIT;
	str_info->status = STREAM_INIT;
	return sst_drop_stream(ctx, str_id);
}
Exemple #3
0
/**
* sst_process_message - Processes message from SST
*
* @work:	Pointer to work structure
*
* This function is scheduled by ISR
* It take a msg from process_queue and does action based on msg
*/
void sst_process_message(struct work_struct *work)
{
	struct sst_ipc_msg_wq *msg =
			container_of(work, struct sst_ipc_msg_wq, wq);
	int str_id = msg->header.part.str_id;

	pr_debug("IPC process for %x\n", msg->header.full);

	/* based on msg in list call respective handler */
	switch (msg->header.part.msg_id) {
	case IPC_SST_BUF_UNDER_RUN:
	case IPC_SST_BUF_OVER_RUN:
		if (sst_validate_strid(str_id)) {
			pr_err("stream id %d invalid\n", str_id);
			break;
		}
		pr_err("Buffer under/overrun for %d\n",
				msg->header.part.str_id);
		pr_err("Got Underrun & not to send data...ignore\n");
		break;

	case IPC_SST_GET_PLAY_FRAMES:
		if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) {
			struct stream_info *stream ;

			if (sst_validate_strid(str_id)) {
				pr_err("strid %d invalid\n", str_id);
				break;
			}
			/* call sst_play_frame */
			stream = &sst_drv_ctx->streams[str_id];
			pr_debug("sst_play_frames for %d\n",
					msg->header.part.str_id);
			mutex_lock(&sst_drv_ctx->streams[str_id].lock);
			sst_play_frame(msg->header.part.str_id);
			mutex_unlock(&sst_drv_ctx->streams[str_id].lock);
			break;
		} else
			pr_err("sst_play_frames for Penwell!!\n");

	case IPC_SST_GET_CAPT_FRAMES:
		if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) {
			struct stream_info *stream;
			/* call sst_capture_frame */
			if (sst_validate_strid(str_id)) {
				pr_err("str id %d invalid\n", str_id);
				break;
			}
			stream = &sst_drv_ctx->streams[str_id];
			pr_debug("sst_capture_frames for %d\n",
					msg->header.part.str_id);
			mutex_lock(&stream->lock);
			if (stream->mmapped == false &&
					stream->src == SST_DRV) {
				pr_debug("waking up block for copy.\n");
				stream->data_blk.ret_code = 0;
				stream->data_blk.condition = true;
				stream->data_blk.on = false;
				wake_up(&sst_drv_ctx->wait_queue);
			} else
				sst_capture_frame(msg->header.part.str_id);
			mutex_unlock(&stream->lock);
		} else
			pr_err("sst_play_frames for Penwell!!\n");
		break;

	case IPC_IA_PRINT_STRING:
		pr_debug("been asked to print something by fw\n");
		/* TBD */
		break;

	case IPC_IA_FW_INIT_CMPLT: {
		/* send next data to FW */
		process_fw_init(msg);
		break;
	}

	case IPC_SST_STREAM_PROCESS_FATAL_ERR:
		if (sst_validate_strid(str_id)) {
			pr_err("stream id %d invalid\n", str_id);
			break;
		}
		pr_err("codec fatal error %x stream %d...\n",
				msg->header.full, msg->header.part.str_id);
		pr_err("Dropping the stream\n");
		sst_drop_stream(msg->header.part.str_id);
		break;
	case IPC_IA_LPE_GETTING_STALLED:
		sst_drv_ctx->lpe_stalled = 1;
		break;
	case IPC_IA_LPE_UNSTALLED:
		sst_drv_ctx->lpe_stalled = 0;
		break;
	default:
		/* Illegal case */
		pr_err("Unhandled msg %x header %x\n",
		msg->header.part.msg_id, msg->header.full);
	}
	sst_clear_interrupt();
	return;
}
Exemple #4
0
static int sst_cdev_stream_drop(struct device *dev, unsigned int str_id)
{
	struct intel_sst_drv *ctx = dev_get_drvdata(dev);

	return sst_drop_stream(ctx, str_id);
}