static int snd_card_saudio_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { const struct snd_saudio *saudio = snd_pcm_substream_chip(substream); const int stream_id = substream->pstr->stream; const int dev = substream->pcm->device; struct saudio_dev_ctrl *dev_ctrl = NULL; struct saudio_stream *stream = NULL; struct saudio_msg msg = { 0 }; int err = 0; int result = 0; ADEBUG(); dev_ctrl = (struct saudio_dev_ctrl *)&(saudio->dev_ctrl[dev]); stream = (struct saudio_stream *)&(dev_ctrl->stream[stream_id]); switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: msg.stream_id = stream_id; stream->stream_state = SAUDIO_TRIGGERED; result = saudio_data_trigger_process(stream, &msg); result = saudio_send_common_cmd(dev_ctrl->dst, dev_ctrl->channel, SAUDIO_CMD_START, stream->stream_id,0); if (result) { ETRACE("saudio.c: snd_card_saudio_pcm_trigger: RESUME, send_common_cmd result is %d", result); saudio_snd_card_free(saudio); return result; } break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: stream->stream_state = SAUDIO_STOPPED; result = saudio_send_common_cmd(dev_ctrl->dst, dev_ctrl->channel, SAUDIO_CMD_STOP, stream->stream_id, 0); if (result) { ETRACE("saudio.c: snd_card_saudio_pcm_trigger: SUSPEND, send_common_cmd result is %d", result); saudio_snd_card_free(saudio); return result; } break; default: err = -EINVAL; break; } return 0; }
static int snd_card_saudio_pcm_close(struct snd_pcm_substream *substream) { const struct snd_saudio *saudio = snd_pcm_substream_chip(substream); const int stream_id = substream->pstr->stream; const int dev = substream->pcm->device; struct saudio_dev_ctrl *dev_ctrl = NULL; int result = 0; ADEBUG(); pr_info("%s IN, stream_id=%d\n", __func__, stream_id); dev_ctrl = (struct saudio_dev_ctrl *)&(saudio->dev_ctrl[dev]); mutex_lock(&dev_ctrl->mutex); result = saudio_send_common_cmd(dev_ctrl->dst, dev_ctrl->channel, SAUDIO_CMD_CLOSE, stream_id,CMD_TIMEOUT); if (result) { ETRACE("saudio.c: snd_card_saudio_pcm_close: saudio_send_common_cmd result is %d", result); saudio_snd_card_free(saudio); mutex_unlock(&dev_ctrl->mutex); return result; } pr_info("%s send cmd done\n", __func__); result = saudio_wait_common_cmd(dev_ctrl->dst, dev_ctrl->channel, SAUDIO_CMD_CLOSE_RET, 0,CMD_TIMEOUT); if(result) saudio_snd_card_free(saudio); mutex_unlock(&dev_ctrl->mutex); pr_info("%s OUT, result=%d\n", __func__, result); return result; }
static int snd_card_saudio_pcm_open(struct snd_pcm_substream *substream) { const struct snd_saudio *saudio = snd_pcm_substream_chip(substream); const int stream_id = substream->pstr->stream; const int dev = substream->pcm->device; struct snd_pcm_runtime *runtime = substream->runtime; struct saudio_stream *stream = NULL; int result = 0; struct saudio_dev_ctrl *dev_ctrl = NULL; ADEBUG(); pr_info("%s IN, stream_id=%d\n", __func__, stream_id); dev_ctrl = (struct saudio_dev_ctrl *)&(saudio->dev_ctrl[dev]); stream = (struct saudio_stream *)&(dev_ctrl->stream[stream_id]); stream->substream = substream; stream->stream_id = stream_id; stream->period = 0; stream->periods_tosend = 0; stream->periods_avail = 0; stream->hwptr_done = 0; stream->last_getblk_count = 0; stream->last_elapsed_count = 0; stream->blk_count = SAUDIO_STREAM_BLOCK_COUNT; if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { runtime->hw = snd_card_saudio_playback; } else { runtime->hw = snd_card_saudio_capture; } mutex_lock(&dev_ctrl->mutex); saudio_clear_ctrl_cmd(saudio); result = saudio_send_common_cmd(dev_ctrl->dst, dev_ctrl->channel, SAUDIO_CMD_OPEN, stream_id,CMD_TIMEOUT); if (result) { ETRACE("saudio.c: snd_card_saudio_pcm_open: saudio_send_common_cmd result is %d", result); saudio_snd_card_free(saudio); mutex_unlock(&dev_ctrl->mutex); return result; } pr_info("%s send cmd done\n", __func__); result = saudio_wait_common_cmd(dev_ctrl->dst, dev_ctrl->channel, SAUDIO_CMD_OPEN_RET, 0,CMD_TIMEOUT); if(result) saudio_snd_card_free(saudio); mutex_unlock(&dev_ctrl->mutex); pr_info("%s OUT, result=%d\n", __func__, result); return result; }
static void saudio_work_card_free_handler(struct work_struct *data) { struct snd_saudio *saudio = container_of(data, struct snd_saudio, card_free_work); printk(KERN_INFO "saudio: card free handler in\n"); if (saudio->card) { int result; printk(KERN_INFO "saudio: work_handler:snd card free in,dst %d, channel %d\n", saudio->dst, saudio->channel); mutex_lock(&saudio->mutex); saudio->state = 0; mutex_unlock(&saudio->mutex); if (!saudio->in_init) saudio_send_common_cmd(saudio->dst, saudio->channel, 0, SAUDIO_CMD_HANDSHAKE, -1); printk(KERN_INFO "saudio: work_handler:snd card free reulst %d,dst %d, channel %d\n", result, saudio->dst, saudio->channel); } printk(KERN_INFO "saudio: card free handler out\n"); }
static void saudio_snd_wait_modem_restart(struct snd_saudio *saudio) { struct saudio_dev_ctrl *dev_ctrl = NULL; int result = 0; dev_ctrl = &saudio->dev_ctrl[0]; while (1) { result = saudio_wait_common_cmd(dev_ctrl->dst, dev_ctrl->monitor_channel, SAUDIO_CMD_HANDSHAKE, 0, -1); if (result) { schedule_timeout_interruptible(msecs_to_jiffies(1000)); printk(KERN_ERR "saudio_wait_monitor_cmd error %d\n", result); continue; } else { while (1) { result = saudio_send_common_cmd(dev_ctrl->dst, dev_ctrl-> monitor_channel, SAUDIO_CMD_HANDSHAKE_RET, 0, -1); if (!result) { break; } printk(KERN_ERR "saudio_send_monitor_cmd error %d\n", result); schedule_timeout_interruptible(msecs_to_jiffies (1000)); } } break; } }
static int saudio_snd_notify_modem_clear(struct snd_saudio *saudio) { struct saudio_dev_ctrl *dev_ctrl = NULL; int result = 0; dev_ctrl = &saudio->dev_ctrl[0]; printk(KERN_INFO "saudio.c:saudio_snd_notify_mdem_clear in"); result = saudio_send_common_cmd(dev_ctrl->dst, dev_ctrl->monitor_channel, SAUDIO_CMD_RESET, 0, -1); if (result) { printk(KERN_ERR "saudio_send_modem_reset_cmd error %d\n", result); } else { result = saudio_wait_common_cmd(dev_ctrl->dst, dev_ctrl->monitor_channel, SAUDIO_CMD_RESET_RET, 0, CMD_MODEM_RESET_TIMEOUT); if (result) { printk(KERN_ERR "saudio_wait_monitor_cmd error %d\n", result); } } printk(KERN_INFO "saudio.c:saudio_snd_notify_mdem_clear out"); return result; }