diff options
Diffstat (limited to 'sound/x86/intel_hdmi_audio.c')
-rw-r--r-- | sound/x86/intel_hdmi_audio.c | 90 |
1 files changed, 25 insertions, 65 deletions
diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index a34d7d9c2a57..378826312abe 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -1024,19 +1024,21 @@ static void wait_clear_underrun_bit(struct snd_intelhad *intelhaddata) dev_err(intelhaddata->dev, "Unable to clear UNDERRUN bits\n"); } -/* Perform some reset procedure but only when need_reset is set; +/* Perform some reset procedure after stopping the stream; * this is called from prepare or hw_free callbacks once after trigger STOP * or underrun has been processed in order to settle down the h/w state. */ -static void had_do_reset(struct snd_intelhad *intelhaddata) +static int had_pcm_sync_stop(struct snd_pcm_substream *substream) { - if (!intelhaddata->need_reset || !intelhaddata->connected) - return; + struct snd_intelhad *intelhaddata = snd_pcm_substream_chip(substream); + + if (!intelhaddata->connected) + return 0; /* Reset buffer pointers */ had_reset_audio(intelhaddata); wait_clear_underrun_bit(intelhaddata); - intelhaddata->need_reset = false; + return 0; } /* called from irq handler */ @@ -1050,7 +1052,6 @@ static void had_process_buffer_underrun(struct snd_intelhad *intelhaddata) snd_pcm_stop_xrun(substream); had_substream_put(intelhaddata); } - intelhaddata->need_reset = true; } /* @@ -1142,19 +1143,6 @@ static int had_pcm_hw_params(struct snd_pcm_substream *substream, } /* - * ALSA PCM hw_free callback - */ -static int had_pcm_hw_free(struct snd_pcm_substream *substream) -{ - struct snd_intelhad *intelhaddata; - - intelhaddata = snd_pcm_substream_chip(substream); - had_do_reset(intelhaddata); - - return 0; -} - -/* * ALSA PCM trigger callback */ static int had_pcm_trigger(struct snd_pcm_substream *substream, int cmd) @@ -1178,7 +1166,6 @@ static int had_pcm_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* Disable Audio */ had_enable_audio(intelhaddata, false); - intelhaddata->need_reset = true; break; default: @@ -1210,8 +1197,6 @@ static int had_pcm_prepare(struct snd_pcm_substream *substream) dev_dbg(intelhaddata->dev, "rate=%d\n", runtime->rate); dev_dbg(intelhaddata->dev, "channels=%d\n", runtime->channels); - had_do_reset(intelhaddata); - /* Get N value in KHz */ disp_samp_freq = intelhaddata->tmds_clock_speed; @@ -1287,9 +1272,9 @@ static const struct snd_pcm_ops had_pcm_ops = { .open = had_pcm_open, .close = had_pcm_close, .hw_params = had_pcm_hw_params, - .hw_free = had_pcm_hw_free, .prepare = had_pcm_prepare, .trigger = had_pcm_trigger, + .sync_stop = had_pcm_sync_stop, .pointer = had_pcm_pointer, .mmap = had_pcm_mmap, }; @@ -1672,11 +1657,6 @@ static void hdmi_lpe_audio_free(struct snd_card *card) cancel_work_sync(&ctx->hdmi_audio_wq); } - - if (card_ctx->mmio_start) - iounmap(card_ctx->mmio_start); - if (card_ctx->irq >= 0) - free_irq(card_ctx->irq, card_ctx); } /* @@ -1714,8 +1694,8 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev) } /* create a card instance with ALSA framework */ - ret = snd_card_new(&pdev->dev, hdmi_card_index, hdmi_card_id, - THIS_MODULE, sizeof(*card_ctx), &card); + ret = snd_devm_card_new(&pdev->dev, hdmi_card_index, hdmi_card_id, + THIS_MODULE, sizeof(*card_ctx), &card); if (ret) return ret; @@ -1751,20 +1731,20 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev) __func__, (unsigned int)res_mmio->start, (unsigned int)res_mmio->end); - card_ctx->mmio_start = ioremap(res_mmio->start, - (size_t)(resource_size(res_mmio))); + card_ctx->mmio_start = + devm_ioremap(&pdev->dev, res_mmio->start, + (size_t)(resource_size(res_mmio))); if (!card_ctx->mmio_start) { dev_err(&pdev->dev, "Could not get ioremap\n"); - ret = -EACCES; - goto err; + return -EACCES; } /* setup interrupt handler */ - ret = request_irq(irq, display_pipe_interrupt_handler, 0, - pdev->name, card_ctx); + ret = devm_request_irq(&pdev->dev, irq, display_pipe_interrupt_handler, + 0, pdev->name, card_ctx); if (ret < 0) { dev_err(&pdev->dev, "request_irq failed\n"); - goto err; + return ret; } card_ctx->irq = irq; @@ -1784,7 +1764,7 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev) ret = snd_pcm_new(card, INTEL_HAD, port, MAX_PB_STREAMS, MAX_CAP_STREAMS, &pcm); if (ret) - goto err; + return ret; /* setup private data which can be retrieved when required */ pcm->private_data = ctx; @@ -1796,7 +1776,7 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev) /* allocate dma pages; * try to allocate 600k buffer as default which is large enough */ - snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV_UC, + snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV_WC, card->dev, HAD_DEFAULT_BUFFER, HAD_MAX_BUFFER); @@ -1805,31 +1785,29 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev) struct snd_kcontrol *kctl; kctl = snd_ctl_new1(&had_controls[i], ctx); - if (!kctl) { - ret = -ENOMEM; - goto err; - } + if (!kctl) + return -ENOMEM; kctl->id.device = pcm->device; ret = snd_ctl_add(card, kctl); if (ret < 0) - goto err; + return ret; } /* Register channel map controls */ ret = had_register_chmap_ctls(ctx, pcm); if (ret < 0) - goto err; + return ret; ret = had_create_jack(ctx, pcm); if (ret < 0) - goto err; + return ret; } ret = snd_card_register(card); if (ret) - goto err; + return ret; spin_lock_irq(&pdata->lpe_audio_slock); pdata->notify_audio_lpe = notify_audio_lpe; @@ -1846,23 +1824,6 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev) } return 0; - -err: - snd_card_free(card); - return ret; -} - -/* - * hdmi_lpe_audio_remove - stop bridge with i915 - * - * This function is called when the platform device is destroyed. - */ -static int hdmi_lpe_audio_remove(struct platform_device *pdev) -{ - struct snd_intelhad_card *card_ctx = platform_get_drvdata(pdev); - - snd_card_free(card_ctx->card); - return 0; } static const struct dev_pm_ops hdmi_lpe_audio_pm = { @@ -1875,7 +1836,6 @@ static struct platform_driver hdmi_lpe_audio_driver = { .pm = &hdmi_lpe_audio_pm, }, .probe = hdmi_lpe_audio_probe, - .remove = hdmi_lpe_audio_remove, }; module_platform_driver(hdmi_lpe_audio_driver); |