diff options
-rw-r--r-- | sound/drivers/intel_mid_hdmi/intel_mid_hdmi_audio.c | 58 | ||||
-rw-r--r-- | sound/drivers/intel_mid_hdmi/intel_mid_hdmi_audio.h | 6 | ||||
-rw-r--r-- | sound/drivers/intel_mid_hdmi/intel_mid_hdmi_audio_if.c | 215 |
3 files changed, 81 insertions, 198 deletions
diff --git a/sound/drivers/intel_mid_hdmi/intel_mid_hdmi_audio.c b/sound/drivers/intel_mid_hdmi/intel_mid_hdmi_audio.c index 1b3943398ee..46e36e05e2b 100644 --- a/sound/drivers/intel_mid_hdmi/intel_mid_hdmi_audio.c +++ b/sound/drivers/intel_mid_hdmi/intel_mid_hdmi_audio.c @@ -381,12 +381,12 @@ int snd_intelhad_prog_buffer(struct snd_intelhad *intelhaddata, struct snd_pcm_substream *substream; substream = intelhaddata->stream_info.had_substream; - if (!substream) { pr_err("substream is NULL\n"); dump_stack(); return 0; } + ring_buf_addr = substream->runtime->dma_addr; ring_buf_size = snd_pcm_lib_buffer_bytes(substream); intelhaddata->stream_info.ring_buf_size = ring_buf_size; @@ -579,7 +579,8 @@ static int snd_intelhad_open(struct snd_pcm_substream *substream) return -ENODEV; } if (had_stream->process_trigger != NO_TRIGGER) { - pr_err("%s:Yet to process some trigger\n", __func__); + pr_err("%s:Yet to process some trigger = %d\n", __func__, + had_stream->process_trigger); return -EAGAIN; } runtime = substream->runtime; @@ -807,7 +808,7 @@ int snd_intelhad_start_silence(struct snd_intelhad *intelhaddata) intelhaddata->valid_buf_cnt = HAD_MAX_PERIODS; intelhaddata->curr_buf = HAD_BUF_TYPE_C; had_stream = intelhaddata->private_data; - had_stream->stream_status = HAD_RUNNING_SILENCE; + had_stream->stream_type = HAD_RUNNING_SILENCE; spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); had_read_modify(AUD_CONFIG, 1, BIT(0)); @@ -825,7 +826,7 @@ int snd_intelhad_stop_silence(struct snd_intelhad *intelhaddata) spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); had_stream = intelhaddata->private_data; - had_stream->stream_status = HAD_INIT; + had_stream->stream_type = HAD_INIT; spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); had_read_modify(AUD_CONFIG, 0, BIT(0)); @@ -907,16 +908,14 @@ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, switch (cmd) { case SNDRV_PCM_TRIGGER_START: pr_debug("Trigger Start\n"); - stream->substream = substream; - stream->stream_status = STREAM_RUNNING; /* Disable local INTRs till register prgmng is done */ if (had_get_hwstate(intelhaddata)) { pr_err("_START: HDMI cable plugged-out\n"); - snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED); retval = -ENODEV; break; } + stream->stream_status = STREAM_RUNNING; spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irq); had_stream->process_trigger = PRE_START; @@ -931,22 +930,17 @@ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, intelhaddata->stream_info.str_id = 0; /* Stop reporting BUFFER_DONE/UNDERRUN to above layers*/ - had_stream->process_trigger = STOP_TRIGGER; - /* Send zero filled data */ - if (had_stream->stream_status == HAD_RUNNING_DUMMY) { - had_stream->stream_status = HAD_INIT; - had_stream->process_trigger = NO_TRIGGER; - spin_unlock_irqrestore(&intelhaddata->had_spinlock, - flag_irq); - cancel_delayed_work(&intelhaddata->dummy_audio); - } else if (intelhaddata->drv_status != HAD_DRV_DISCONNECTED) { + + if (intelhaddata->drv_status != HAD_DRV_DISCONNECTED) { + had_stream->process_trigger = STOP_TRIGGER; spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irq); if (!had_get_hwstate(intelhaddata)) snd_process_stop_trigger(intelhaddata); - } else + } else { spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irq); + } stream->stream_status = STREAM_DROPPED; break; @@ -1000,7 +994,6 @@ static int snd_intelhad_pcm_prepare(struct snd_pcm_substream *substream) pr_debug("rate=%d\n", runtime->rate); pr_debug("channels=%d\n", runtime->channels); - intelhaddata = snd_pcm_substream_chip(substream); if (intelhaddata->stream_info.str_id) { pr_debug("_prepare is called for existing str_id#%d\n", intelhaddata->stream_info.str_id); @@ -1122,32 +1115,6 @@ out: return retval; } -void dummy_audio_play(struct work_struct *work) -{ - struct snd_intelhad *intelhaddata = had_data; - struct had_pvt_data *had_stream; - unsigned long flag_irqs; - - spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); - if (intelhaddata->drv_status != HAD_DRV_DISCONNECTED) { - spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); - pr_debug("HDMI device still connected\n"); - return; - } - had_stream = intelhaddata->private_data; - - /* In case _STOP, silence data, return */ - if (had_stream->stream_status < HAD_RUNNING_STREAM) { - spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); - pr_debug("HDMI device_flag is reset\n"); - return; - } - - spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); - had_event_handler(HAD_EVENT_AUDIO_BUFFER_DONE, intelhaddata); - schedule_delayed_work(&intelhaddata->dummy_audio, intelhaddata->timer); -} - /*PCM operations structure and the calls back for the same */ struct snd_pcm_ops snd_intelhad_playback_ops = { .open = snd_intelhad_open, @@ -1369,9 +1336,6 @@ static int __devinit hdmi_audio_probe(struct platform_device *devptr) if (retval < 0) goto err; - /* Initialize dummy audio workqueue */ - INIT_DELAYED_WORK(&intelhaddata->dummy_audio, dummy_audio_play); - /* Allocate memory for flat data */ intelhaddata->flat_data = kzalloc((MAX_SZ_ZERO_BUF), GFP_KERNEL); if (!intelhaddata->flat_data) { diff --git a/sound/drivers/intel_mid_hdmi/intel_mid_hdmi_audio.h b/sound/drivers/intel_mid_hdmi/intel_mid_hdmi_audio.h index ca4de7ca3ed..ab8c673e6ea 100644 --- a/sound/drivers/intel_mid_hdmi/intel_mid_hdmi_audio.h +++ b/sound/drivers/intel_mid_hdmi/intel_mid_hdmi_audio.h @@ -98,7 +98,6 @@ enum had_status_stream { HAD_INIT = 0, HAD_RUNNING_SILENCE = 1, HAD_RUNNING_STREAM = 2, - HAD_RUNNING_DUMMY = 3, }; /** @@ -425,12 +424,11 @@ struct ring_buf_info { struct had_stream_pvt { enum had_stream_status stream_status; int stream_ops; - struct snd_pcm_substream *substream; ssize_t dbg_cum_bytes; }; struct had_pvt_data { - enum had_status_stream stream_status; + enum had_status_stream stream_type; enum had_process_trigger process_trigger; }; @@ -470,8 +468,6 @@ struct snd_intelhad { unsigned int aes_bits; int flag_underrun; struct had_pvt_data *private_data; - /* Related to sending dummy data */ - struct delayed_work dummy_audio; unsigned long timer; /* Related to sending silence data */ char *flat_data; diff --git a/sound/drivers/intel_mid_hdmi/intel_mid_hdmi_audio_if.c b/sound/drivers/intel_mid_hdmi/intel_mid_hdmi_audio_if.c index f43831d1b89..173f8f29edd 100644 --- a/sound/drivers/intel_mid_hdmi/intel_mid_hdmi_audio_if.c +++ b/sound/drivers/intel_mid_hdmi/intel_mid_hdmi_audio_if.c @@ -59,7 +59,7 @@ int hdmi_audio_query(void *haddata, hdmi_audio_event_t event) case HAD_EVENT_QUERY_IS_AUDIO_BUSY: spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); - if ((had_stream->stream_status > HAD_RUNNING_SILENCE) || + if ((had_stream->stream_type > HAD_RUNNING_SILENCE) || substream) { spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); @@ -113,7 +113,7 @@ int hdmi_audio_suspend(void *haddata, hdmi_audio_event_t event) substream = intelhaddata->stream_info.had_substream; spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); - if ((had_stream->stream_status > HAD_RUNNING_SILENCE) || substream) { + if ((had_stream->stream_type > HAD_RUNNING_SILENCE) || substream) { spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); pr_err("audio stream is active\n"); return -EAGAIN; @@ -229,45 +229,6 @@ static inline int had_chk_intrmiss(struct snd_intelhad *intelhaddata, return intr_count; } -static inline int had_start_dummy_playback(struct snd_intelhad *intelhaddata) -{ - int retval = 0; - enum intel_had_aud_buf_type buf_id; - u32 buf_size; - struct snd_pcm_substream *substream; - struct had_pvt_data *had_stream; - u32 msecs, rate, channels; - unsigned long flag_irqs; - - pr_debug("Enter:%s", __func__); - - spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); - had_stream = intelhaddata->private_data; - buf_id = intelhaddata->curr_buf; - substream = intelhaddata->stream_info.had_substream; - - if ((had_stream->stream_status < HAD_RUNNING_DUMMY) && substream - && substream->runtime) { - had_stream->stream_status = HAD_RUNNING_DUMMY; - spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); - pr_debug("Steam active, start dummy_playback\n"); - /* In case substream is active, start reporting - * dummy buffer_done interrupts to above ALSA layer. - */ - buf_size = intelhaddata->buf_info[buf_id].buf_size; - rate = substream->runtime->rate; - channels = substream->runtime->channels; - msecs = (buf_size*1000)/(rate*channels*4); - intelhaddata->timer = msecs_to_jiffies(msecs); - schedule_delayed_work( - &intelhaddata->dummy_audio, - intelhaddata->timer); - } else - spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); - - return retval; -} - static inline int had_process_pre_start(struct snd_intelhad *intelhaddata, enum intel_had_aud_buf_type buf_id) { @@ -277,10 +238,19 @@ static inline int had_process_pre_start(struct snd_intelhad *intelhaddata, enum intel_had_aud_buf_type inv_start; unsigned long flag_irqs; + + spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); had_stream = intelhaddata->private_data; + /* Check for device state*/ + if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { + spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + pr_err("%s:Cable plugged-out\n", __func__); + return retval; + } + spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); if (intelhaddata->valid_buf_cnt-1 == buf_id) { - if (had_stream->stream_status >= HAD_RUNNING_STREAM) + if (had_stream->stream_type == HAD_RUNNING_STREAM) buf_id = HAD_BUF_TYPE_A; else /* Use only silence buffers C & D */ buf_id = HAD_BUF_TYPE_C; @@ -309,7 +279,7 @@ static inline int had_process_pre_start(struct snd_intelhad *intelhaddata, if (buf_id != HAD_BUF_TYPE_A) had_stream->process_trigger = START_TRIGGER; else { - had_stream->stream_status = HAD_RUNNING_STREAM; + had_stream->stream_type = HAD_RUNNING_STREAM; had_stream->process_trigger = NO_TRIGGER; } spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); @@ -328,22 +298,15 @@ static inline int had_process_start_trigger(struct snd_intelhad *intelhaddata) had_stream = intelhaddata->private_data; spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); - /* Check for device state - * In case, _DISCONNECTED, start dummy_playback - * if not done - */ + /* Check for device state*/ if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { - spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); - pr_debug("Cable plugged-out\n"); - retval = had_start_dummy_playback(intelhaddata); - spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); had_stream->process_trigger = NO_TRIGGER; - intelhaddata->curr_buf = HAD_BUF_TYPE_A; spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + pr_err("%s:Cable plugged-out\n", __func__); return retval; } - had_stream->stream_status = HAD_RUNNING_STREAM; + had_stream->stream_type = HAD_RUNNING_STREAM; had_stream->process_trigger = NO_TRIGGER; intelhaddata->curr_buf = HAD_BUF_TYPE_A; prg_start = intelhaddata->buff_done; @@ -364,15 +327,9 @@ static inline int had_process_stop_trigger(struct snd_intelhad *intelhaddata) had_stream = intelhaddata->private_data; buf_id = intelhaddata->curr_buf; - /* If device disconnected, ignore this interrupt */ - if (had_stream->stream_status == HAD_RUNNING_DUMMY) { - had_stream->stream_status = HAD_INIT; - had_stream->process_trigger = NO_TRIGGER; - return retval; - } /* All successive intr for Silence stream */ - had_stream->stream_status = HAD_RUNNING_SILENCE; + had_stream->stream_type = HAD_RUNNING_SILENCE; had_stream->process_trigger = NO_TRIGGER; /* If buf_id < HAD_BUF_TYPE_C, ignore */ @@ -417,7 +374,7 @@ int had_process_buffer_done(struct snd_intelhad *intelhaddata) u32 buf_size; struct had_pvt_data *had_stream; int intr_count; - enum had_stream_status stream_status; + enum had_status_stream stream_type; enum had_process_trigger process_trigger; unsigned long flag_irqs; @@ -426,11 +383,16 @@ int had_process_buffer_done(struct snd_intelhad *intelhaddata) intr_count = 1; spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); + if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { + spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + pr_err("%s:Device already disconnected\n", __func__); + return retval; + } buf_id = intelhaddata->curr_buf; intelhaddata->buff_done = buf_id; buff_done = intelhaddata->buff_done; buf_size = intelhaddata->buf_info[buf_id].buf_size; - stream_status = had_stream->stream_status; + stream_type = had_stream->stream_type; process_trigger = had_stream->process_trigger; pr_debug("Enter:%s buf_id=%d", __func__, buf_id); @@ -441,7 +403,7 @@ int had_process_buffer_done(struct snd_intelhad *intelhaddata) */ /* Check for any intr_miss in case of active playback */ - if ((had_stream->stream_status == HAD_RUNNING_STREAM) && + if ((had_stream->stream_type == HAD_RUNNING_STREAM) && (had_stream->process_trigger == NO_TRIGGER) && !flag_en_allbufs) { spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); @@ -484,18 +446,13 @@ int had_process_buffer_done(struct snd_intelhad *intelhaddata) intelhaddata->buf_info[buf_id].is_valid = true; if (intelhaddata->valid_buf_cnt-1 == buf_id) { - if (had_stream->stream_status >= HAD_RUNNING_STREAM) + if (had_stream->stream_type >= HAD_RUNNING_STREAM) intelhaddata->curr_buf = HAD_BUF_TYPE_A; else /* Use only silence buffers C & D */ intelhaddata->curr_buf = HAD_BUF_TYPE_C; } else intelhaddata->curr_buf = buf_id + 1; - if (had_stream->stream_status == HAD_RUNNING_DUMMY) { - spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); - goto exit; - } - spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); if (had_get_hwstate(intelhaddata)) { @@ -519,12 +476,12 @@ int had_process_buffer_done(struct snd_intelhad *intelhaddata) had_read_register(AUD_BUF_A_LENGTH + (buf_id * HAD_REG_WIDTH), &len); pr_debug("%s:Enabled buf[%d]\n", __func__, buf_id); -exit: - /* In case of actual/dummy data, + + /* In case of actual data, * report buffer_done to above ALSA layer */ buf_size = intelhaddata->buf_info[buf_id].buf_size; - if (stream_status >= HAD_RUNNING_STREAM) { + if (stream_type >= HAD_RUNNING_STREAM) { intelhaddata->stream_info.buffer_rendered += (intr_count * buf_size); stream->period_elapsed(stream->had_substream); @@ -539,33 +496,30 @@ int had_process_buffer_underrun(struct snd_intelhad *intelhaddata) enum intel_had_aud_buf_type buf_id; struct pcm_stream_info *stream; struct had_pvt_data *had_stream; - enum had_stream_status stream_status; + enum had_status_stream stream_type; enum had_process_trigger process_trigger; u32 hdmi_status; unsigned long flag_irqs; + int drv_status; had_stream = intelhaddata->private_data; stream = &intelhaddata->stream_info; spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); buf_id = intelhaddata->curr_buf; - stream_status = had_stream->stream_status; + stream_type = had_stream->stream_type; process_trigger = had_stream->process_trigger; intelhaddata->buff_done = buf_id; - if (stream_status == HAD_RUNNING_STREAM) + drv_status = intelhaddata->drv_status; + if (stream_type == HAD_RUNNING_STREAM) intelhaddata->curr_buf = HAD_BUF_TYPE_A; else /* Use only silence buffers C & D */ intelhaddata->curr_buf = HAD_BUF_TYPE_C; spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); - pr_debug("Enter:%s buf_id=%d, stream_status=%d, process_trigger=%d\n", - __func__, buf_id, stream_status, process_trigger); - - if (stream_status == HAD_RUNNING_DUMMY) { - pr_err("_UNDERRUN occured during dummy playback\n"); - return retval; - } + pr_debug("Enter:%s buf_id=%d, stream_type=%d, process_trigger=%d\n", + __func__, buf_id, stream_type, process_trigger); /* Handle Underrun interrupt within Audio Unit */ had_write_register(AUD_CONFIG, 0); @@ -590,8 +544,12 @@ int had_process_buffer_underrun(struct snd_intelhad *intelhaddata) } while (i < MAX_CNT); if (i >= MAX_CNT) pr_err("Unable to clear UNDERRUN bits\n"); + if (drv_status == HAD_DRV_DISCONNECTED) { + pr_err("%s:Device already disconnected\n", __func__); + return retval; + } - if (stream_status == HAD_RUNNING_STREAM) { + if (stream_type == HAD_RUNNING_STREAM) { if (process_trigger == NO_TRIGGER) { /* Report UNDERRUN error to above layers */ intelhaddata->flag_underrun = 1; @@ -613,11 +571,11 @@ int had_process_buffer_underrun(struct snd_intelhad *intelhaddata) return retval; } else { pr_err("%s:Should never come here\n", __func__); - pr_err("stream_status=%d,process_trigger=%d\n", - stream_status, process_trigger); + pr_err("stream_type=%d,process_trigger=%d\n", + stream_type, process_trigger); return retval; } - } else if (stream_status == HAD_RUNNING_SILENCE) { + } else if (stream_type == HAD_RUNNING_SILENCE) { if (process_trigger < START_TRIGGER) retval = snd_intelhad_start_silence(intelhaddata); else if (process_trigger == START_TRIGGER) { @@ -625,7 +583,7 @@ int had_process_buffer_underrun(struct snd_intelhad *intelhaddata) flag_irqs); intelhaddata->curr_buf = HAD_BUF_TYPE_A; had_stream->process_trigger = NO_TRIGGER; - had_stream->stream_status = HAD_RUNNING_STREAM; + had_stream->stream_type = HAD_RUNNING_STREAM; spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); had_read_modify(AUD_CONFIG, 1, BIT(0)); @@ -634,8 +592,8 @@ int had_process_buffer_underrun(struct snd_intelhad *intelhaddata) /* Pre start already processed */ } else { pr_err("%s:Should never come here\n", __func__); - pr_err("stream_status=%d,process_trigger=%d\n", - stream_status, process_trigger); + pr_err("stream_type=%d,process_trigger=%d\n", + stream_type, process_trigger); return retval; } } @@ -649,7 +607,6 @@ int had_process_hot_plug(struct snd_intelhad *intelhaddata) enum intel_had_aud_buf_type buf_id; struct snd_pcm_substream *substream; struct had_pvt_data *had_stream; - enum had_stream_status stream_status; unsigned long flag_irqs; pr_debug("Enter:%s", __func__); @@ -666,64 +623,27 @@ int had_process_hot_plug(struct snd_intelhad *intelhaddata) buf_id = intelhaddata->curr_buf; intelhaddata->buff_done = buf_id; intelhaddata->drv_status = HAD_DRV_CONNECTED; - buf_id = intelhaddata->curr_buf; - stream_status = had_stream->stream_status; spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); pr_debug("Processing HOT_PLUG, buf_id = %d\n", buf_id); - if (stream_status == HAD_INIT) { - /* Start sending silence data */ - pr_debug("Start sending SILENCE\n"); - caps = HDMI_AUDIO_UNDERRUN | HDMI_AUDIO_BUFFER_DONE; - retval = had_set_caps(HAD_SET_ENABLE_AUDIO_INT, &caps); - retval = had_set_caps(HAD_SET_ENABLE_AUDIO, NULL); - retval = snd_intelhad_configure_silence(intelhaddata); - retval = snd_intelhad_start_silence(intelhaddata); - return retval; - } /* Safety check */ - if (!substream) { - pr_err("PANIC!!! Should never come here\n"); - return retval; + if (substream) { + pr_debug("There should not be active PB from ALSA\n"); + pr_debug("Signifies, cable is plugged-in even before\n"); + pr_debug("processing snd_pcm_disconnect\n"); + /* Set runtime->state to hw_params done */ + snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP); } - if (stream_status == HAD_RUNNING_DUMMY) { - spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); - had_stream->stream_status = HAD_RUNNING_STREAM; - flag_en_allbufs = 1; - spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); - cancel_delayed_work(&intelhaddata->dummy_audio); - } + /* Start sending silence data */ + pr_debug("Start sending SILENCE\n"); caps = HDMI_AUDIO_UNDERRUN | HDMI_AUDIO_BUFFER_DONE; retval = had_set_caps(HAD_SET_ENABLE_AUDIO_INT, &caps); retval = had_set_caps(HAD_SET_ENABLE_AUDIO, NULL); - /* Reset HW within Audio unit */ - had_write_register(AUD_CONFIG, 0); - had_write_register(AUD_HDMI_STATUS, 1); - had_write_register(AUD_HDMI_STATUS, 0); - - /*Reprogram the registers with addr and length*/ - pr_debug("Enabling Bottom half buffers after _PLUG\n"); - /* If all buffs already enabled, - * No need to enable Top half buffers - */ - if (buf_id == HAD_BUF_TYPE_A) - flag_en_allbufs = 0; - retval = snd_intelhad_prog_buffer(intelhaddata, buf_id, HAD_BUF_TYPE_D); - - if (substream) { /* continue transfer */ - snd_intelhad_init_audio_ctrl(substream, - intelhaddata, 0); - hdmi_audio_mode_change(substream); - } - if (buf_id == HAD_BUF_TYPE_D) { /* Enable all remaining buffs now*/ - retval = snd_intelhad_prog_buffer(intelhaddata, HAD_BUF_TYPE_A, - (buf_id-1)); - flag_en_allbufs = 0; - } - + snd_intelhad_configure_silence(intelhaddata); + retval = snd_intelhad_start_silence(intelhaddata); return retval; } @@ -731,7 +651,6 @@ int had_process_hot_unplug(struct snd_intelhad *intelhaddata) { int caps, retval = 0; enum intel_had_aud_buf_type buf_id; - struct snd_pcm_substream *substream; struct had_pvt_data *had_stream; unsigned long flag_irqs; @@ -739,7 +658,6 @@ int had_process_hot_unplug(struct snd_intelhad *intelhaddata) had_stream = intelhaddata->private_data; buf_id = intelhaddata->curr_buf; - substream = intelhaddata->stream_info.had_substream; spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { @@ -755,15 +673,20 @@ int had_process_hot_unplug(struct snd_intelhad *intelhaddata) } intelhaddata->drv_status = HAD_DRV_DISCONNECTED; - - if (had_stream->stream_status == HAD_RUNNING_STREAM) { - spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); - had_start_dummy_playback(intelhaddata); - } else { - had_stream->stream_status = HAD_INIT; + /* Report to above ALSA layer */ + if (intelhaddata->stream_info.had_substream != NULL) { + had_stream->process_trigger = NO_TRIGGER; spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + pr_debug("%s: unlock -> sending pcm_stop -> lock\n", __func__); + snd_pcm_stop(intelhaddata->stream_info.had_substream, + SNDRV_PCM_STATE_DISCONNECTED); + spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); } + had_stream->stream_type = HAD_INIT; + spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + pr_debug("%s: unlocked -> returned\n", __func__); + return retval; } @@ -822,7 +745,7 @@ int had_event_handler(enum had_event_type event_type, void *data) break; } spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); - if ((had_stream->stream_status == HAD_RUNNING_STREAM) + if ((had_stream->stream_type == HAD_RUNNING_STREAM) && substream) retval = hdmi_audio_mode_change(substream); break; |