From patchwork Thu Jul 6 11:14:45 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oder Chiou X-Patchwork-Id: 9828047 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 9798760317 for ; Thu, 6 Jul 2017 11:15:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8573428614 for ; Thu, 6 Jul 2017 11:15:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 762182861C; Thu, 6 Jul 2017 11:15:05 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 12D8128614 for ; Thu, 6 Jul 2017 11:15:03 +0000 (UTC) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 00EDE266B1C; Thu, 6 Jul 2017 13:15:01 +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 E3F7D266FA2; Thu, 6 Jul 2017 13:14:58 +0200 (CEST) Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) by alsa0.perex.cz (Postfix) with ESMTP id 11E452664EB for ; Thu, 6 Jul 2017 13:14:52 +0200 (CEST) Authenticated-By: X-SpamFilter-By: BOX Solutions SpamTrap 5.59 with qID v66BEnBH028603, This message is accepted by code: ctloc85258 Received: from mail.realtek.com (rtitcas12.realtek.com.tw [172.21.6.16]) by rtits2.realtek.com.tw (8.15.2/2.55/5.73) with ESMTP id v66BEnBH028603; Thu, 6 Jul 2017 19:14:49 +0800 Received: from RTITCASV01.realtek.com.tw (172.21.6.18) by RTITCAS12.realtek.com.tw (172.21.6.16) with Microsoft SMTP Server (TLS) id 14.3.319.2; Thu, 6 Jul 2017 19:14:49 +0800 Received: from localhost.localdomain (172.21.85.85) by RTITCASV01.realtek.com.tw (172.21.6.18) with Microsoft SMTP Server id 14.3.294.0; Thu, 6 Jul 2017 19:14:48 +0800 From: Oder Chiou To: , Date: Thu, 6 Jul 2017 19:14:45 +0800 Message-ID: <1499339685-3112-1-git-send-email-oder_chiou@realtek.com> X-Mailer: git-send-email 2.7.4 MIME-Version: 1.0 X-Originating-IP: [172.21.85.85] Cc: Oder Chiou , jack.yu@realtek.com, alsa-devel@alsa-project.org, hychao@google.com, albertchen@realtek.com, shumingf@realtek.com, bardliao@realtek.com, flove@realtek.com Subject: [alsa-devel] [PATCH] ASoC: rt5514: Support the DSP recording continuously after the hotwording triggered 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 The patch uses the IRQ to copy the PCM data to userspace continuously after the hotwording triggered from DSP. Signed-off-by: Oder Chiou --- sound/soc/codecs/rt5514-spi.c | 147 +++++++++++++++++++++++------------------- sound/soc/codecs/rt5514-spi.h | 7 +- 2 files changed, 84 insertions(+), 70 deletions(-) diff --git a/sound/soc/codecs/rt5514-spi.c b/sound/soc/codecs/rt5514-spi.c index 7ed62e8..5884850 100644 --- a/sound/soc/codecs/rt5514-spi.c +++ b/sound/soc/codecs/rt5514-spi.c @@ -39,13 +39,12 @@ static struct spi_device *rt5514_spi; struct rt5514_dsp { struct device *dev; + struct work_struct start_work; struct delayed_work copy_work; struct mutex dma_lock; struct snd_pcm_substream *substream; unsigned int buf_base, buf_limit, buf_rp; - size_t buf_size; - size_t dma_offset; - size_t dsp_offset; + size_t buf_size, get_size, dma_offset; }; static const struct snd_pcm_hardware rt5514_spi_pcm_hardware = { @@ -80,6 +79,8 @@ static void rt5514_spi_copy_work(struct work_struct *work) container_of(work, struct rt5514_dsp, copy_work.work); struct snd_pcm_runtime *runtime; size_t period_bytes, truncated_bytes = 0; + unsigned int cur_wp, remain_data; + u8 buf[8]; mutex_lock(&rt5514_dsp->dma_lock); if (!rt5514_dsp->substream) { @@ -90,8 +91,22 @@ static void rt5514_spi_copy_work(struct work_struct *work) runtime = rt5514_dsp->substream->runtime; period_bytes = snd_pcm_lib_period_bytes(rt5514_dsp->substream); - if (rt5514_dsp->buf_size - rt5514_dsp->dsp_offset < period_bytes) - period_bytes = rt5514_dsp->buf_size - rt5514_dsp->dsp_offset; + if (rt5514_dsp->get_size >= rt5514_dsp->buf_size) { + rt5514_spi_burst_read(RT5514_BUFFER_VOICE_WP, (u8 *)&buf, + sizeof(buf)); + cur_wp = buf[0] | buf[1] << 8 | buf[2] << 16 | + buf[3] << 24; + + remain_data = (cur_wp >= rt5514_dsp->buf_rp) ? + (cur_wp - rt5514_dsp->buf_rp) : + ((rt5514_dsp->buf_limit - rt5514_dsp->buf_rp) + + (cur_wp - rt5514_dsp->buf_base)); + + if (remain_data < period_bytes) { + schedule_delayed_work(&rt5514_dsp->copy_work, 5); + goto done; + } + } if (rt5514_dsp->buf_rp + period_bytes <= rt5514_dsp->buf_limit) { rt5514_spi_burst_read(rt5514_dsp->buf_rp, @@ -112,24 +127,57 @@ static void rt5514_spi_copy_work(struct work_struct *work) runtime->dma_area + rt5514_dsp->dma_offset + truncated_bytes, period_bytes - truncated_bytes); - rt5514_dsp->buf_rp = rt5514_dsp->buf_base + - period_bytes - truncated_bytes; + rt5514_dsp->buf_rp = rt5514_dsp->buf_base + period_bytes - + truncated_bytes; } + rt5514_dsp->get_size += period_bytes; rt5514_dsp->dma_offset += period_bytes; if (rt5514_dsp->dma_offset >= runtime->dma_bytes) rt5514_dsp->dma_offset = 0; - rt5514_dsp->dsp_offset += period_bytes; - snd_pcm_period_elapsed(rt5514_dsp->substream); - if (rt5514_dsp->dsp_offset < rt5514_dsp->buf_size) - schedule_delayed_work(&rt5514_dsp->copy_work, 5); + schedule_delayed_work(&rt5514_dsp->copy_work, 5); + done: mutex_unlock(&rt5514_dsp->dma_lock); } +static void rt5514_spi_start_work(struct work_struct *work) +{ + struct rt5514_dsp *rt5514_dsp = + container_of(work, struct rt5514_dsp, start_work); + u8 buf[8]; + + rt5514_dsp->get_size = 0; + rt5514_dsp->dma_offset = 0; + + /** + * The address area x1800XXXX is the register address, and it cannot + * support spi burst read perfectly. So we use the spi burst read + * individually to make sure the data correctly. + */ + rt5514_spi_burst_read(RT5514_BUFFER_VOICE_BASE, (u8 *)&buf, + sizeof(buf)); + rt5514_dsp->buf_base = buf[0] | buf[1] << 8 | buf[2] << 16 | + buf[3] << 24; + + rt5514_spi_burst_read(RT5514_BUFFER_VOICE_LIMIT, (u8 *)&buf, + sizeof(buf)); + rt5514_dsp->buf_limit = buf[0] | buf[1] << 8 | buf[2] << 16 | + buf[3] << 24; + + rt5514_spi_burst_read(RT5514_BUFFER_VOICE_WP, (u8 *)&buf, + sizeof(buf)); + rt5514_dsp->buf_rp = buf[0] | buf[1] << 8 | buf[2] << 16 | + buf[3] << 24; + + rt5514_dsp->buf_size = rt5514_dsp->buf_limit - rt5514_dsp->buf_base; + + schedule_delayed_work(&rt5514_dsp->copy_work, 0); +} + /* PCM for streaming audio from the DSP buffer */ static int rt5514_spi_pcm_open(struct snd_pcm_substream *substream) { @@ -170,59 +218,6 @@ static int rt5514_spi_hw_free(struct snd_pcm_substream *substream) return snd_pcm_lib_free_vmalloc_buffer(substream); } -static int rt5514_spi_prepare(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct rt5514_dsp *rt5514_dsp = - snd_soc_platform_get_drvdata(rtd->platform); - u8 buf[8]; - - rt5514_dsp->dma_offset = 0; - rt5514_dsp->dsp_offset = 0; - - /** - * The address area x1800XXXX is the register address, and it cannot - * support spi burst read perfectly. So we use the spi burst read - * individually to make sure the data correctly. - */ - rt5514_spi_burst_read(RT5514_BUFFER_VOICE_BASE, (u8 *)&buf, - sizeof(buf)); - rt5514_dsp->buf_base = buf[0] | buf[1] << 8 | buf[2] << 16 | - buf[3] << 24; - - rt5514_spi_burst_read(RT5514_BUFFER_VOICE_LIMIT, (u8 *)&buf, - sizeof(buf)); - rt5514_dsp->buf_limit = buf[0] | buf[1] << 8 | buf[2] << 16 | - buf[3] << 24; - - rt5514_spi_burst_read(RT5514_BUFFER_VOICE_RP, (u8 *)&buf, - sizeof(buf)); - rt5514_dsp->buf_rp = buf[0] | buf[1] << 8 | buf[2] << 16 | - buf[3] << 24; - - rt5514_spi_burst_read(RT5514_BUFFER_VOICE_SIZE, (u8 *)&buf, - sizeof(buf)); - rt5514_dsp->buf_size = buf[0] | buf[1] << 8 | buf[2] << 16 | - buf[3] << 24; - - return 0; -} - -static int rt5514_spi_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct rt5514_dsp *rt5514_dsp = - snd_soc_platform_get_drvdata(rtd->platform); - - if (cmd == SNDRV_PCM_TRIGGER_START) { - if (rt5514_dsp->buf_base && rt5514_dsp->buf_limit && - rt5514_dsp->buf_rp && rt5514_dsp->buf_size) - schedule_delayed_work(&rt5514_dsp->copy_work, 0); - } - - return 0; -} - static snd_pcm_uframes_t rt5514_spi_pcm_pointer( struct snd_pcm_substream *substream) { @@ -238,25 +233,45 @@ static const struct snd_pcm_ops rt5514_spi_pcm_ops = { .open = rt5514_spi_pcm_open, .hw_params = rt5514_spi_hw_params, .hw_free = rt5514_spi_hw_free, - .trigger = rt5514_spi_trigger, - .prepare = rt5514_spi_prepare, .pointer = rt5514_spi_pcm_pointer, .mmap = snd_pcm_lib_mmap_vmalloc, .page = snd_pcm_lib_get_vmalloc_page, }; +static irqreturn_t rt5514_spi_irq(int irq, void *data) +{ + struct rt5514_dsp *rt5514_dsp = data; + + schedule_work(&rt5514_dsp->start_work); + + return IRQ_HANDLED; +} + static int rt5514_spi_pcm_probe(struct snd_soc_platform *platform) { struct rt5514_dsp *rt5514_dsp; + int ret; rt5514_dsp = devm_kzalloc(platform->dev, sizeof(*rt5514_dsp), GFP_KERNEL); rt5514_dsp->dev = &rt5514_spi->dev; mutex_init(&rt5514_dsp->dma_lock); + INIT_WORK(&rt5514_dsp->start_work, rt5514_spi_start_work); INIT_DELAYED_WORK(&rt5514_dsp->copy_work, rt5514_spi_copy_work); snd_soc_platform_set_drvdata(platform, rt5514_dsp); + if (rt5514_spi->irq) { + ret = devm_request_threaded_irq(&rt5514_spi->dev, + rt5514_spi->irq, NULL, rt5514_spi_irq, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, "rt5514-spi", + rt5514_dsp); + if (ret) + dev_err(&rt5514_spi->dev, + "%s Failed to reguest IRQ: %d\n", __func__, + ret); + } + return 0; } diff --git a/sound/soc/codecs/rt5514-spi.h b/sound/soc/codecs/rt5514-spi.h index f69b1cd..a6434ee 100644 --- a/sound/soc/codecs/rt5514-spi.h +++ b/sound/soc/codecs/rt5514-spi.h @@ -17,10 +17,9 @@ */ #define RT5514_SPI_BUF_LEN 240 -#define RT5514_BUFFER_VOICE_BASE 0x18001034 -#define RT5514_BUFFER_VOICE_LIMIT 0x18001038 -#define RT5514_BUFFER_VOICE_RP 0x1800103c -#define RT5514_BUFFER_VOICE_SIZE 0x18001040 +#define RT5514_BUFFER_VOICE_BASE 0x18000200 +#define RT5514_BUFFER_VOICE_LIMIT 0x18000204 +#define RT5514_BUFFER_VOICE_WP 0x1800020c /* SPI Command */ enum {