From patchwork Wed May 14 16:59:48 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: JongHo Kim X-Patchwork-Id: 4176251 Return-Path: X-Original-To: patchwork-alsa-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id A261EBFF02 for ; Wed, 14 May 2014 17:00:16 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 97C2B201F9 for ; Wed, 14 May 2014 17:00:15 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id 1E60F2017B for ; Wed, 14 May 2014 17:00:14 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id 2D82D2608ED; Wed, 14 May 2014 19:00:11 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-1.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, NO_DNS_FOR_FROM, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=no version=3.3.1 Received: from alsa0.perex.cz (localhost [IPv6:::1]) by alsa0.perex.cz (Postfix) with ESMTP id 289D126109C; Wed, 14 May 2014 19:00:00 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 984AE26109E; Wed, 14 May 2014 18:59:58 +0200 (CEST) Received: from mail-yh0-f41.google.com (mail-yh0-f41.google.com [209.85.213.41]) by alsa0.perex.cz (Postfix) with ESMTP id D808C2608ED; Wed, 14 May 2014 18:59:49 +0200 (CEST) Received: by mail-yh0-f41.google.com with SMTP id f73so1929495yha.14 for ; Wed, 14 May 2014 09:59:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:cc:content-type; bh=HQjPfrSbFMU0hVwhYr0JpH5iz2VJVtqYisfWEuGIqQU=; b=U1fVY/4HgmilgVxvFloW1IwoP2/wq15fM8zAJT6i+3DIetaV8y3ZcELJ4rWm9BWxYc mIPGt7nQHUQtFRak/Bm1XVj5aADbJ9Ep/a9yOPNUijZ80VhhpymkQ8/DnPUG1KZ3j0K6 +PLiG1YvBF0jNXnZNqS1D3S/EfojNgq6QvJuNaXvIsrZTLVjbDDfcJGggmbqhd5C4c2w EpG8m6Zo/rn+xDMqm505AMotKgbn0FP2UGb4acGhTf1Q9t9qu0FEQs8jXUrJ3w0DN5tO HqGrSFfxAR3jFLJqL5T9bP7mbk4Of7ja/4bmtb3QwgH/f61fZIAexY4tWzHZNPatQj5l OZfQ== MIME-Version: 1.0 X-Received: by 10.236.120.66 with SMTP id o42mr7220196yhh.66.1400086788667; Wed, 14 May 2014 09:59:48 -0700 (PDT) Received: by 10.170.55.73 with HTTP; Wed, 14 May 2014 09:59:48 -0700 (PDT) Date: Thu, 15 May 2014 01:59:48 +0900 Message-ID: From: JongHo Kim To: Jaroslav Kysela , Abramo Bagnara , Takashi Iwai , Mark Brown , Liam Girdwood X-Content-Filtered-By: Mailman/MimeDel 2.1.14 Cc: alsa-devel@alsa-project.org Subject: [alsa-devel] [Resend] Add the stream report feature. Could you review my idea? X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP (Add the alsa-devel@alsa-project.org) Hi I am work on ASoC part and developing the smartphone(Android). we have been doing the stress and long runtime test. audio output is no problem but I sometimes face the "playback write error(DMA or IRQ trouble?)" error message. I know the meaning of the message and I can solve the error. the problem may be caused by AP(clk) or I2S or DMA or Codec. I would like to trace the hardware error at the printed message. Could you review my idea? Thanks --- include/sound/pcm.h | 2 ++ include/sound/soc-dai.h | 2 ++ include/sound/soc.h | 1 + sound/core/pcm_lib.c | 3 +++ sound/core/pcm_native.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ sound/soc/soc-pcm.c | 26 +++++++++++++++++++++++++ 6 files changed, 85 insertions(+) struct snd_soc_pcm_runtime *be, int stream) @@ -2267,6 +2291,7 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) rtd->ops.close = dpcm_fe_dai_close; rtd->ops.pointer = soc_pcm_pointer; rtd->ops.ioctl = soc_pcm_ioctl; + rtd->ops.report = soc_pcm_report; } else { rtd->ops.open = soc_pcm_open; rtd->ops.hw_params = soc_pcm_hw_params; @@ -2276,6 +2301,7 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) rtd->ops.close = soc_pcm_close; rtd->ops.pointer = soc_pcm_pointer; rtd->ops.ioctl = soc_pcm_ioctl; + rtd->ops.report = soc_pcm_report; } if (platform->driver->ops) { diff --git a/include/sound/pcm.h b/include/sound/pcm.h index b4d6697..cd3093a 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -82,6 +82,7 @@ struct snd_pcm_ops { unsigned long offset); int (*mmap)(struct snd_pcm_substream *substream, struct vm_area_struct *vma); int (*ack)(struct snd_pcm_substream *substream); + void (*report)(struct snd_pcm_substream *substream); }; /* @@ -502,6 +503,7 @@ int snd_pcm_status(struct snd_pcm_substream *substream, int snd_pcm_start(struct snd_pcm_substream *substream); int snd_pcm_stop(struct snd_pcm_substream *substream, snd_pcm_state_t status); int snd_pcm_drain_done(struct snd_pcm_substream *substream); +void snd_pcm_report(struct snd_pcm_substream *substream); #ifdef CONFIG_PM int snd_pcm_suspend(struct snd_pcm_substream *substream); int snd_pcm_suspend_all(struct snd_pcm *pcm); diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index fad7676..c032393 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -184,6 +184,8 @@ struct snd_soc_dai_ops { struct snd_soc_dai *); int (*bespoke_trigger)(struct snd_pcm_substream *, int, struct snd_soc_dai *); + void (*report)(struct snd_pcm_substream *, + struct snd_soc_dai *); /* * For hardware based FIFO caused delay reporting. * Optional. diff --git a/include/sound/soc.h b/include/sound/soc.h index 0b83168..7685839 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -641,6 +641,7 @@ struct snd_soc_ops { int (*hw_free)(struct snd_pcm_substream *); int (*prepare)(struct snd_pcm_substream *); int (*trigger)(struct snd_pcm_substream *, int); + void (*report)(struct snd_pcm_substream *); }; struct snd_soc_compr_ops { diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index ce83def..0d6c9a3 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -1944,6 +1944,9 @@ static int wait_for_avail(struct snd_pcm_substream *substream, "%s write error (DMA or IRQ trouble?)\n", is_playback ? "playback" : "capture"); err = -EIO; + snd_pcm_stream_unlock_irq(substream); + snd_pcm_report(substream); + snd_pcm_stream_lock_irq(substream); break; } } diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index b653ab0..0ccdc10 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -978,6 +978,57 @@ int snd_pcm_drain_done(struct snd_pcm_substream *substream) SNDRV_PCM_STATE_SETUP); } +void snd_pcm_report(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + + if (!runtime) { + snd_printd("runtime disappear\n"); + return; + } + + mutex_lock(&substream->pcm->open_mutex); + snd_printd("access: %i\n", runtime->access); + snd_printd("format: %i\n", runtime->format); + snd_printd("subformat: %d\n", runtime->subformat); + snd_printd("channels: %u\n", runtime->channels); + snd_printd("rate: %u (%u/%u)\n", runtime->rate, runtime->rate_num, + runtime->rate_den); + snd_printd("period_size: %lu\n", runtime->period_size); + snd_printd("buffer_size: %lu\n", runtime->buffer_size); + snd_printd("tstamp_mode: %i\n", runtime->tstamp_mode); + snd_printd("period_step: %u\n", runtime->period_step); + snd_printd("avail_min: %lu\n", runtime->control->avail_min); + snd_printd("start_threshold: %lu\n", runtime->start_threshold); + snd_printd("stop_threshold: %lu\n", runtime->stop_threshold); + snd_printd("silence_threshold: %lu\n", runtime->silence_threshold); + snd_printd("silence_size: %lu\n", runtime->silence_size); + snd_printd("boundary: %lu\n", runtime->boundary); + snd_printd("state: %i\n", runtime->status->state); + snd_printd("owner_pid: %d\n", pid_vnr(substream->pid)); + snd_printd("trigger_time: %ld.%09ld\n", + runtime->trigger_tstamp.tv_sec, + runtime->trigger_tstamp.tv_nsec); + snd_printd("tstamp: %ld.%09ld\n", + runtime->status->tstamp.tv_sec, + runtime->status->tstamp.tv_nsec); + snd_printd("delay: %ld\n", runtime->delay); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + snd_printd("avail: %ld\n", snd_pcm_playback_avail(runtime)); + else + snd_printd("avail: %ld\n", snd_pcm_capture_avail(runtime)); + snd_printd("avail_max: %ld\n", runtime->avail_max); + snd_printd("hw_ptr: %ld\n", runtime->status->hw_ptr); + snd_printd("appl_ptr: %ld\n", runtime->control->appl_ptr); + + mutex_unlock(&substream->pcm->open_mutex); + + if (substream->ops->report) + substream->ops->report(substream); + + return; +} + /* * pause callbacks */ diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 2cedf09..98a47b3 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -883,6 +883,30 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream) return offset; } +static void soc_pcm_report(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_platform *platform = rtd->platform; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + + mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); + /* report the audio subsystem */ + if (rtd->dai_link->ops && rtd->dai_link->ops->report) + rtd->dai_link->ops->report(substream); + + if (cpu_dai->driver->ops->report) + cpu_dai->driver->ops->report(substream, cpu_dai); + + if (platform->driver->ops && platform->driver->ops->report) + platform->driver->ops->report(substream); + + if (codec_dai->driver->ops->report) + codec_dai->driver->ops->report(substream, codec_dai); + + mutex_unlock(&rtd->pcm_mutex); +} + /* connect a FE and BE */ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe,