static int saudio_ctrl_thread(void *data) { int result = 0; struct snd_saudio *saudio = (struct snd_saudio *)data; ADEBUG(); result = saudio_snd_init_ipc(saudio); if (result) { printk(KERN_ERR "saudio:saudio_snd_init_ipc error %d\n", result); return -1; } while (!kthread_should_stop()) { printk(KERN_INFO "%s,saudio: waiting for modem boot handshake,dst %d,channel %d\n", __func__, saudio->dst, saudio->channel); saudio_snd_wait_modem_restart(saudio); saudio->in_init = 1; printk(KERN_INFO "%s,saudio: modem boot and handshake ok,dst %d, channel %d\n", __func__, saudio->dst, saudio->channel); saudio_snd_card_free(saudio); printk(KERN_INFO "saudio_ctrl_thread flush work queue in dst %d, channel %d\n", saudio->dst, saudio->channel); flush_workqueue(saudio->queue); saudio->in_init = 0; printk(KERN_INFO "saudio_ctrl_thread flush work queue out,dst %d, channel %d\n", saudio->dst, saudio->channel); if(saudio_snd_notify_modem_clear(saudio)) { printk(KERN_ERR " saudio_ctrl_thread modem error again when notify modem clear \n"); continue; } saudio_clear_ctrl_cmd(saudio); if(!saudio->card) { result = saudio_snd_init_card(saudio); printk(KERN_INFO "saudio: snd card init reulst %d, dst %d, channel %d\n", result, saudio->dst, saudio->channel); } mutex_lock(&saudio->mutex); saudio->state = 1; mutex_unlock(&saudio->mutex); } ETRACE("saudio_ctrl_thread create ok\n"); return 0; }
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; }