From patchwork Wed Jun 2 01:34:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takashi Sakamoto X-Patchwork-Id: 12292587 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D0400C4708F for ; Wed, 2 Jun 2021 01:36:06 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 122AE613D0 for ; Wed, 2 Jun 2021 01:36:06 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 122AE613D0 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=sakamocchi.jp Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 9EDAF16E7; Wed, 2 Jun 2021 03:35:14 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 9EDAF16E7 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1622597764; bh=OpOwX55kqfXWxKPnLFZ4B3u5m2ILnIK3hE6hvWuiDc0=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=Zt9UIrvTyT8zN/2NWzAVvoqaUcYU/WFcTlf26AiNYn/HJEB9DJgykaQ7mtDsaV7w5 EO192swjVpNKmnH0t26IqaZ4ja1DrOtkbjvL/imy20q33EDu4E/zSraXpNQaTRXgRK g+OkrPIszQHQhkOjyTI1Spg87mW8gmT6oT03NsIk= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 3CDD0F802A9; Wed, 2 Jun 2021 03:34:26 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id CF5C9F804BB; Wed, 2 Jun 2021 03:34:24 +0200 (CEST) Received: from wout4-smtp.messagingengine.com (wout4-smtp.messagingengine.com [64.147.123.20]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 85C78F802A9 for ; Wed, 2 Jun 2021 03:34:15 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 85C78F802A9 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=sakamocchi.jp header.i=@sakamocchi.jp header.b="wc+unqed"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="h3YmpX4b" Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.west.internal (Postfix) with ESMTP id 6E76115A9; Tue, 1 Jun 2021 21:34:13 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute5.internal (MEProxy); Tue, 01 Jun 2021 21:34:13 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sakamocchi.jp; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=fm1; bh=ieMbjFiFptira qHvAmxKvyj1/JInKkD1FLO2aNy4Eow=; b=wc+unqedmVeOevl88KkGralkGVrh5 VgJJ6Fcwxdj37mHV43K4gfYRFFZAMtb2mJtqP2DKsPEq5yCkMZtwB2Vp9dPXDpA+ b5J4hPbGI3FtGqLGDOjGsAW1T9YyzSqlELBsFfDPBkhfJMPAkZhbD52N42wTdWtH ugRnWxokLd/RDY2oe+Ds8eAoIhMSSRSJV88QsJdNCO1iXWl4Fa8/Hxu75/e0Ply0 jISKlfIdvr86+peEAxQosciRJ2y5PB7PbnBBuslFa6Nf8+42t2ebjxkan80Vn9qb drSRAqU6ycThvDHVF71ZuH7f2Rfm+kAfIpga/xDAb/rjhPfSRX2h+ns7Q== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm2; bh=ieMbjFiFptiraqHvAmxKvyj1/JInKkD1FLO2aNy4Eow=; b=h3YmpX4b ObpLzSbuGnZ8a0nNlLJzyKCXUGOI/C3dsmqdc8GYcAQuje8MyFwpH26Mdf92INNF G6yKxZKo82qtmHsfdGTv16ubqkoB4n8Cu33PtZVfDRCEoHDmRLpiPJNzwInFYmFc LwlnOAi3y+TR6gbb/UbZomrkQ9KeqRRWlM3bxWa6JGjYsLMoJ8IBwyv/OfRxzmsv 3zbsKLnyBzjv4HeA7SmbarzAErWyY3SCY7eLnaPvpgkG9KltAnQOO4Zhp28Jb+IT vayJzZ3NFfc/N/NrU8Q+IoeV7sMaA3mK42hy0im39QABjnua1Utj+4I5m5WZ4CUS Zd7c1m83qBDKOw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduledrvdeliedggeekucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefhvffufffkofgjfhgggfestdekre dtredttdenucfhrhhomhepvfgrkhgrshhhihcuufgrkhgrmhhothhouceoohdqthgrkhgr shhhihesshgrkhgrmhhotggthhhirdhjpheqnecuggftrfgrthhtvghrnhepveefffefke etgfevgeefleehfffhueejtdejveethfekveektdejjedvtdejhfejnecuvehluhhsthgv rhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomhepohdqthgrkhgrshhhihessh grkhgrmhhotggthhhirdhjph X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 1 Jun 2021 21:34:11 -0400 (EDT) From: Takashi Sakamoto To: tiwai@suse.de Subject: [PATCH 1/3] ALSA: firewire-motu: use macro for magic numbers relevant to IEC 61883-1 Date: Wed, 2 Jun 2021 10:34:04 +0900 Message-Id: <20210602013406.26442-2-o-takashi@sakamocchi.jp> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210602013406.26442-1-o-takashi@sakamocchi.jp> References: <20210602013406.26442-1-o-takashi@sakamocchi.jp> MIME-Version: 1.0 Cc: alsa-devel@alsa-project.org, clemens@ladisch.de X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 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" ALSA firewire-motu driver has some magic numbers from IEC 61883-1 to operates source packet header (SPH). This commit replaces them with macros. Signed-off-by: Takashi Sakamoto --- sound/firewire/motu/amdtp-motu.c | 40 +++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/sound/firewire/motu/amdtp-motu.c b/sound/firewire/motu/amdtp-motu.c index 18bf433f43b6..89638e1fbb69 100644 --- a/sound/firewire/motu/amdtp-motu.c +++ b/sound/firewire/motu/amdtp-motu.c @@ -16,6 +16,18 @@ #define CIP_FMT_MOTU_TX_V3 0x22 #define MOTU_FDF_AM824 0x22 +#define TICKS_PER_CYCLE 3072 +#define CYCLES_PER_SECOND 8000 +#define TICKS_PER_SECOND (TICKS_PER_CYCLE * CYCLES_PER_SECOND) + +#define IEEE1394_SEC_MODULUS 128 + +#define TRANSFER_DELAY_TICKS 0x2e00 /* 479.17 microseconds */ + +#define CIP_SPH_CYCLE_SHIFT 12 +#define CIP_SPH_CYCLE_MASK 0x01fff000 +#define CIP_SPH_OFFSET_MASK 0x00000fff + /* * Nominally 3125 bytes/second, but the MIDI port's clock might be * 1% too slow, and the bus clock 100 ppm too fast. @@ -97,17 +109,16 @@ int amdtp_motu_set_parameters(struct amdtp_stream *s, unsigned int rate, p->midi_db_count = 0; p->midi_db_interval = rate / MIDI_BYTES_PER_SECOND; - /* IEEE 1394 bus requires. */ - delay = 0x2e00; + delay = TRANSFER_DELAY_TICKS; - /* For no-data or empty packets to adjust PCM sampling frequency. */ - delay += 8000 * 3072 * s->syt_interval / rate; + // For no-data or empty packets to adjust PCM sampling frequency. + delay += TICKS_PER_SECOND * s->syt_interval / rate; p->next_seconds = 0; - p->next_cycles = delay / 3072; + p->next_cycles = delay / TICKS_PER_CYCLE; p->quotient_ticks_per_event = params[s->sfc].quotient_ticks_per_event; p->remainder_ticks_per_event = params[s->sfc].remainder_ticks_per_event; - p->next_ticks = delay % 3072; + p->next_ticks = delay % TICKS_PER_CYCLE; p->next_accumulated = 0; return 0; @@ -363,18 +374,18 @@ static inline void compute_next_elapse_from_start(struct amdtp_motu *p) } p->next_ticks += p->quotient_ticks_per_event; - if (p->next_ticks >= 3072) { - p->next_ticks -= 3072; + if (p->next_ticks >= TICKS_PER_CYCLE) { + p->next_ticks -= TICKS_PER_CYCLE; p->next_cycles++; } - if (p->next_cycles >= 8000) { - p->next_cycles -= 8000; + if (p->next_cycles >= CYCLES_PER_SECOND) { + p->next_cycles -= CYCLES_PER_SECOND; p->next_seconds++; } - if (p->next_seconds >= 128) - p->next_seconds -= 128; + if (p->next_seconds >= IEEE1394_SEC_MODULUS) + p->next_seconds -= IEEE1394_SEC_MODULUS; } static void write_sph(struct amdtp_stream *s, __be32 *buffer, unsigned int data_blocks, @@ -386,8 +397,9 @@ static void write_sph(struct amdtp_stream *s, __be32 *buffer, unsigned int data_ u32 sph; for (i = 0; i < data_blocks; i++) { - next_cycles = (rx_start_cycle + p->next_cycles) % 8000; - sph = ((next_cycles << 12) | p->next_ticks) & 0x01ffffff; + next_cycles = (rx_start_cycle + p->next_cycles) % CYCLES_PER_SECOND; + sph = ((next_cycles << CIP_SPH_CYCLE_SHIFT) | p->next_ticks) & + (CIP_SPH_CYCLE_MASK | CIP_SPH_OFFSET_MASK); *buffer = cpu_to_be32(sph); compute_next_elapse_from_start(p); From patchwork Wed Jun 2 01:34:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takashi Sakamoto X-Patchwork-Id: 12292589 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D34F2C4708F for ; Wed, 2 Jun 2021 01:36:11 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 1EB9D613CD for ; Wed, 2 Jun 2021 01:36:11 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1EB9D613CD Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=sakamocchi.jp Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 9A9DF16DB; Wed, 2 Jun 2021 03:35:19 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 9A9DF16DB DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1622597769; bh=vECZOQ4xceWiH14FX7Gr6qdLlCnrRLxv/HkePZalm5M=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=llKrtRNw6Nb0TNfvavK5msF03k82r2eORrH6bPUwOtTnamJw2h7a+GQn3pfkpwuQh Izv41Aj5r9NnFu1jX3G0kekujYDUCEbebM1Lw/PNCjpIubGfiz2XDQucSkGxEJGwMu jj1XOwSKNM2Pde7XW7dN8mPd0EHYQ0SPNejnbA/M= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id DA804F804BB; Wed, 2 Jun 2021 03:34:27 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id EA106F80103; Wed, 2 Jun 2021 03:34:26 +0200 (CEST) Received: from wout4-smtp.messagingengine.com (wout4-smtp.messagingengine.com [64.147.123.20]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id C4ACDF80103 for ; Wed, 2 Jun 2021 03:34:17 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz C4ACDF80103 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=sakamocchi.jp header.i=@sakamocchi.jp header.b="0/uBdB7r"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="HbGABeQC" Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.west.internal (Postfix) with ESMTP id 78FC815CF; Tue, 1 Jun 2021 21:34:15 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute5.internal (MEProxy); Tue, 01 Jun 2021 21:34:15 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sakamocchi.jp; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=fm1; bh=nqj3IV7pqig3a wYigVUQvrgdtHw38viRqXcz1z7UBLo=; b=0/uBdB7ruBN2P19YmQKuFiUMHbGMk P6JhW8wnXWzAt4ygmR3h/Pgi0jLjr1Orncurkwe9ToZEBVR36rTZtVZsG6cOdDWP 5xhNU7njfYdzjNDYINpiWPK5EoskQEbvLOYEdSl6q0pVutpo81QOx5pGtzTy0DX/ h0gWuMkPIM3pWkzevarY/otQn/ATqj9eet9IYfTmZ4cy23ZpgW+aee0EcT1aH76j 86swwCb1UimDnTRvl6Xt/YL+8DzEBBGximutlxMKLd+Y9QMx15nr0qB+PMNPKnk+ P56ibTPFRIt64OYnd8fZvLm/jIIu56svaAa8NP1Pybta+ryg1ZdRYApeg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm2; bh=nqj3IV7pqig3awYigVUQvrgdtHw38viRqXcz1z7UBLo=; b=HbGABeQC pG5xYFZOipbIQ3lVAlDzGxidXowlNaul7G78B7dpJb567Ls9rZS6RIb8cFBlg/Ub iqTUbsMOyTk1V0ZBwXI1GMLGAph/Xrmun23lllkFeqy0cWrPVbnZLPuOPLbqDaz8 5Mg6GjjEJYHo2og5CtjmvhdljZKL2uN6Rqz2+qCTD2di5CR96Ngm02BGC3TCm+u6 JeyR6zPGw5OBy85y6FfX6EGjS7xMqPqiOh7CAQzhd5P8Gd+SNPi9xq2M247Ac6YZ A/ItyWVRTZ5zW9tMujxDedi8Avtai6A/JKC/2PEDRBP53OzWHby4MbLX6ViF6xAf 2bDhlRz/2Uj1uw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduledrvdeliedggeekucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefhvffufffkofgjfhgggfestdekre dtredttdenucfhrhhomhepvfgrkhgrshhhihcuufgrkhgrmhhothhouceoohdqthgrkhgr shhhihesshgrkhgrmhhotggthhhirdhjpheqnecuggftrfgrthhtvghrnhepveefffefke etgfevgeefleehfffhueejtdejveethfekveektdejjedvtdejhfejnecuvehluhhsthgv rhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomhepohdqthgrkhgrshhhihessh grkhgrmhhotggthhhirdhjph X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 1 Jun 2021 21:34:14 -0400 (EDT) From: Takashi Sakamoto To: tiwai@suse.de Subject: [PATCH 2/3] ALSA: firewire-motu: cache event ticks in source packet header per data block Date: Wed, 2 Jun 2021 10:34:05 +0900 Message-Id: <20210602013406.26442-3-o-takashi@sakamocchi.jp> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210602013406.26442-1-o-takashi@sakamocchi.jp> References: <20210602013406.26442-1-o-takashi@sakamocchi.jp> MIME-Version: 1.0 Cc: alsa-devel@alsa-project.org, clemens@ladisch.de X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 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" The devices in MOTU FireWire series put source packet header (SPH) into each data block of tx packet for presentation time of event. The format of timestamp is compliant to IEC 61883-1, with cycle and offset fields without sec field of 32 bit cycle time. This commit takes ALSA firewire-motu driver to cache the presentation time as offset from cycle in which the packet is transferred. Signed-off-by: Takashi Sakamoto --- sound/firewire/motu/amdtp-motu.c | 41 ++++++++++++++++++++++++++++++- sound/firewire/motu/motu-stream.c | 20 ++++++++++++++- sound/firewire/motu/motu.h | 12 ++++++++- 3 files changed, 70 insertions(+), 3 deletions(-) diff --git a/sound/firewire/motu/amdtp-motu.c b/sound/firewire/motu/amdtp-motu.c index 89638e1fbb69..1741ceb381c7 100644 --- a/sound/firewire/motu/amdtp-motu.c +++ b/sound/firewire/motu/amdtp-motu.c @@ -53,6 +53,8 @@ struct amdtp_motu { int midi_db_count; unsigned int midi_db_interval; + + struct amdtp_motu_cache *cache; }; int amdtp_motu_set_parameters(struct amdtp_stream *s, unsigned int rate, @@ -333,6 +335,34 @@ static void probe_tracepoints_events(struct amdtp_stream *s, } } +static void cache_event_offsets(struct amdtp_motu_cache *cache, const __be32 *buf, + unsigned int data_blocks, unsigned int data_block_quadlets) +{ + unsigned int *event_offsets = cache->event_offsets; + const unsigned int cache_size = cache->size; + unsigned int cache_tail = cache->tail; + unsigned int base_tick = cache->tx_cycle_count * TICKS_PER_CYCLE; + int i; + + for (i = 0; i < data_blocks; ++i) { + u32 sph = be32_to_cpu(*buf); + unsigned int tick; + + tick = ((sph & CIP_SPH_CYCLE_MASK) >> CIP_SPH_CYCLE_SHIFT) * TICKS_PER_CYCLE + + (sph & CIP_SPH_OFFSET_MASK); + + if (tick < base_tick) + tick += TICKS_PER_SECOND; + event_offsets[cache_tail] = tick - base_tick; + + cache_tail = (cache_tail + 1) % cache_size; + buf += data_block_quadlets; + } + + cache->tail = cache_tail; + cache->tx_cycle_count = (cache->tx_cycle_count + 1) % CYCLES_PER_SECOND; +} + static unsigned int process_ir_ctx_payloads(struct amdtp_stream *s, const struct pkt_desc *descs, unsigned int packets, @@ -342,12 +372,17 @@ static unsigned int process_ir_ctx_payloads(struct amdtp_stream *s, unsigned int pcm_frames = 0; int i; + if (p->cache->tx_cycle_count == UINT_MAX) + p->cache->tx_cycle_count = (s->domain->processing_cycle.tx_start % CYCLES_PER_SECOND); + // For data block processing. for (i = 0; i < packets; ++i) { const struct pkt_desc *desc = descs + i; __be32 *buf = desc->ctx_payload; unsigned int data_blocks = desc->data_blocks; + cache_event_offsets(p->cache, buf, data_blocks, s->data_block_quadlets); + if (pcm) { read_pcm_s32(s, pcm, buf, data_blocks, pcm_frames); pcm_frames += data_blocks; @@ -449,11 +484,12 @@ static unsigned int process_it_ctx_payloads(struct amdtp_stream *s, int amdtp_motu_init(struct amdtp_stream *s, struct fw_unit *unit, enum amdtp_stream_direction dir, - const struct snd_motu_spec *spec) + const struct snd_motu_spec *spec, struct amdtp_motu_cache *cache) { amdtp_stream_process_ctx_payloads_t process_ctx_payloads; int fmt = CIP_FMT_MOTU; unsigned int flags = CIP_BLOCKING | CIP_UNAWARE_SYT; + struct amdtp_motu *p; int err; if (dir == AMDTP_IN_STREAM) { @@ -493,5 +529,8 @@ int amdtp_motu_init(struct amdtp_stream *s, struct fw_unit *unit, s->ctx_data.rx.fdf = MOTU_FDF_AM824; } + p = s->protocol; + p->cache = cache; + return 0; } diff --git a/sound/firewire/motu/motu-stream.c b/sound/firewire/motu/motu-stream.c index 5d8d067f366d..369002568b2d 100644 --- a/sound/firewire/motu/motu-stream.c +++ b/sound/firewire/motu/motu-stream.c @@ -153,6 +153,9 @@ int snd_motu_stream_reserve_duplex(struct snd_motu *motu, unsigned int rate, fw_iso_resources_free(&motu->tx_resources); fw_iso_resources_free(&motu->rx_resources); + kfree(motu->cache.event_offsets); + motu->cache.event_offsets = NULL; + err = snd_motu_protocol_set_clock_rate(motu, rate); if (err < 0) { dev_err(&motu->unit->device, @@ -181,6 +184,15 @@ int snd_motu_stream_reserve_duplex(struct snd_motu *motu, unsigned int rate, fw_iso_resources_free(&motu->rx_resources); return err; } + + motu->cache.size = motu->tx_stream.syt_interval * frames_per_buffer; + motu->cache.event_offsets = kcalloc(motu->cache.size, sizeof(*motu->cache.event_offsets), + GFP_KERNEL); + if (!motu->cache.event_offsets) { + fw_iso_resources_free(&motu->tx_resources); + fw_iso_resources_free(&motu->rx_resources); + return err; + } } return 0; @@ -260,6 +272,9 @@ int snd_motu_stream_start_duplex(struct snd_motu *motu) if (err < 0) goto stop_streams; + motu->cache.tail = 0; + motu->cache.tx_cycle_count = UINT_MAX; + err = amdtp_domain_start(&motu->domain, 0, false, false); if (err < 0) goto stop_streams; @@ -293,6 +308,9 @@ void snd_motu_stream_stop_duplex(struct snd_motu *motu) fw_iso_resources_free(&motu->tx_resources); fw_iso_resources_free(&motu->rx_resources); + + kfree(motu->cache.event_offsets); + motu->cache.event_offsets = NULL; } } @@ -314,7 +332,7 @@ static int init_stream(struct snd_motu *motu, struct amdtp_stream *s) if (err < 0) return err; - err = amdtp_motu_init(s, motu->unit, dir, motu->spec); + err = amdtp_motu_init(s, motu->unit, dir, motu->spec, &motu->cache); if (err < 0) fw_iso_resources_destroy(resources); diff --git a/sound/firewire/motu/motu.h b/sound/firewire/motu/motu.h index 92effb6e6c96..10ba87062e81 100644 --- a/sound/firewire/motu/motu.h +++ b/sound/firewire/motu/motu.h @@ -39,6 +39,13 @@ struct snd_motu_packet_format { unsigned char pcm_chunks[3]; }; +struct amdtp_motu_cache { + unsigned int *event_offsets; + unsigned int size; + unsigned int tail; + unsigned int tx_cycle_count; +}; + struct snd_motu { struct snd_card *card; struct fw_unit *unit; @@ -70,6 +77,8 @@ struct snd_motu { wait_queue_head_t hwdep_wait; struct amdtp_domain domain; + + struct amdtp_motu_cache cache; }; enum snd_motu_spec_flags { @@ -125,7 +134,8 @@ extern const struct snd_motu_spec snd_motu_spec_4pre; int amdtp_motu_init(struct amdtp_stream *s, struct fw_unit *unit, enum amdtp_stream_direction dir, - const struct snd_motu_spec *spec); + const struct snd_motu_spec *spec, + struct amdtp_motu_cache *cache); int amdtp_motu_set_parameters(struct amdtp_stream *s, unsigned int rate, unsigned int midi_ports, struct snd_motu_packet_format *formats); From patchwork Wed Jun 2 01:34:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takashi Sakamoto X-Patchwork-Id: 12292591 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0E660C4708F for ; Wed, 2 Jun 2021 01:36:47 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8EE20613CD for ; Wed, 2 Jun 2021 01:36:46 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8EE20613CD Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=sakamocchi.jp Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 290C316F5; Wed, 2 Jun 2021 03:35:55 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 290C316F5 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1622597805; bh=9nEdwCE5e/d9jtVh9UHSicFvEeZ/3NsH3xucVQmMZsA=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=iXXdYsDTAL5c/HNWfK/6rpRL6nAeVzOXs7mtXgkW0oWR1zAEMx/AVV4klEjVR0ti2 3JIhd4yW4eVYHc3HlUOEvRvpcVZjh3w+DiEos9ZXpybMZpBrGtY8PHcnZeT66hCIOe rlcPqBj/SLL+mSOcu88o/nsigj11SRXyw6OSLyeI= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 827D1F804BD; Wed, 2 Jun 2021 03:34:29 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 4F913F804BC; Wed, 2 Jun 2021 03:34:27 +0200 (CEST) Received: from wout4-smtp.messagingengine.com (wout4-smtp.messagingengine.com [64.147.123.20]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 2E417F80424 for ; Wed, 2 Jun 2021 03:34:19 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 2E417F80424 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=sakamocchi.jp header.i=@sakamocchi.jp header.b="TugkynzX"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="RaBMbkyR" Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.west.internal (Postfix) with ESMTP id 7A53015C4; Tue, 1 Jun 2021 21:34:17 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Tue, 01 Jun 2021 21:34:17 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sakamocchi.jp; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=fm1; bh=IcNBCVh3Rc2tV REYPvaobN2lnamIDMDPPIMKZ1xOl4s=; b=TugkynzXmQhrJ1ZG+0LWX0NTV3Poj Ri1qJMro8vnS9nVnAkE3XAirxhCCO5JJX9ygSE4fFU0niYPFdhHqRON2MQTNqHAO OdzwTDR6uo05aSwQK0GD5A93FtOVil2BMt4Xs8aZZcsySQqs3IWHSOY/goO/mTYd LPovOymHZc1E2cBhXBUt5Vbe4CyeNAZgu8Uxj8btpsbEL6WbQoih1QRA0SmCdH/p zTQ7rwElIPEffp/KL0RyBs8L7qm9znjibBBrSUyU+4QZBqp0PqXBCxm9SCx/eCG5 zHqo8nYLsOGWOuGHSAFyY1elu/gl6L5SybExifBcVDuEM8lDKMqjleZ0Q== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm2; bh=IcNBCVh3Rc2tVREYPvaobN2lnamIDMDPPIMKZ1xOl4s=; b=RaBMbkyR UoXR6cLlzxbxFbJ3N7NuF6YK1NkixtjDB7CEu/z++wAUNj828vIxXd6PCoi3l2rH vbnAHoNH/C2ixiMht4lznw57qk03h7U0XmS4G4aEUkPLAIhygTKK9zqF/r/SeIMw FP1JOYn4wzxTVnns7Dz8h/XOVBQn8Pk0ouQSnYDJIfTVVnr90uNmWSWMteJrxYAV wlB8rGWJfyCcpSDr7vDwVTrfGZQNaG6RZ/2jTHGXTwgPe51g+Y1Bu7XzSpW7JVeH 7FuCMVRKbHKK/2QpFLrCry0s54cTEoUCsgcCMYT3SpoOO6H398EYTQD265frw3Bv yE/qB0clHOpoBA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduledrvdeliedggeelucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefhvffufffkofgjfhgggfestdekre dtredttdenucfhrhhomhepvfgrkhgrshhhihcuufgrkhgrmhhothhouceoohdqthgrkhgr shhhihesshgrkhgrmhhotggthhhirdhjpheqnecuggftrfgrthhtvghrnhepveefffefke etgfevgeefleehfffhueejtdejveethfekveektdejjedvtdejhfejnecuvehluhhsthgv rhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomhepohdqthgrkhgrshhhihessh grkhgrmhhotggthhhirdhjph X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 1 Jun 2021 21:34:16 -0400 (EDT) From: Takashi Sakamoto To: tiwai@suse.de Subject: [PATCH 3/3] ALSA: firewire-motu: sequence replay for source packet header Date: Wed, 2 Jun 2021 10:34:06 +0900 Message-Id: <20210602013406.26442-4-o-takashi@sakamocchi.jp> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210602013406.26442-1-o-takashi@sakamocchi.jp> References: <20210602013406.26442-1-o-takashi@sakamocchi.jp> MIME-Version: 1.0 Cc: alsa-devel@alsa-project.org, clemens@ladisch.de X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 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" This commit takes ALSA firewire-motu driver to perform sequence replay for media clock recovery. Unlike the other types of device, the devices in MOTU FireWire series require two levels of sequence replay; the sequence of the number of data blocks per packet and the sequence of source packet header per data block. The former is already cached by ALSA IEC 61883-1/6 packet streaming engine and ready to be replayed. The latter is also cached by ALSA firewire-motu driver itself with a previous patch. This commit takes the driver to replay both of them from the caches. The sequence replay is tested with below models: * 828 mkII * Traveler * UltraLite * 828 mk3 FireWire * 828 mk3 Hybrid (except for high sampling transfer frequency * UltraLite mk3 FireWire * 4pre * AudioExpress Unfortunately, below models still don't generate better sound, requires more work: * 8pre * 828 mk3 Hybrid at high sampling transfer frequency As long as I know, MOTU protocol version 1 requires extra care of the format of data block, thus below models are not supported yet in this time: * 828 * 896 Signed-off-by: Takashi Sakamoto --- sound/firewire/motu/amdtp-motu.c | 91 ++++++------------------------- sound/firewire/motu/motu-stream.c | 7 ++- sound/firewire/motu/motu.h | 2 + 3 files changed, 26 insertions(+), 74 deletions(-) diff --git a/sound/firewire/motu/amdtp-motu.c b/sound/firewire/motu/amdtp-motu.c index 1741ceb381c7..5388b85fb60e 100644 --- a/sound/firewire/motu/amdtp-motu.c +++ b/sound/firewire/motu/amdtp-motu.c @@ -20,10 +20,6 @@ #define CYCLES_PER_SECOND 8000 #define TICKS_PER_SECOND (TICKS_PER_CYCLE * CYCLES_PER_SECOND) -#define IEEE1394_SEC_MODULUS 128 - -#define TRANSFER_DELAY_TICKS 0x2e00 /* 479.17 microseconds */ - #define CIP_SPH_CYCLE_SHIFT 12 #define CIP_SPH_CYCLE_MASK 0x01fff000 #define CIP_SPH_OFFSET_MASK 0x00000fff @@ -35,14 +31,6 @@ #define MIDI_BYTES_PER_SECOND 3093 struct amdtp_motu { - /* For timestamp processing. */ - unsigned int quotient_ticks_per_event; - unsigned int remainder_ticks_per_event; - unsigned int next_ticks; - unsigned int next_accumulated; - unsigned int next_cycles; - unsigned int next_seconds; - unsigned int pcm_chunks; unsigned int pcm_byte_offset; @@ -61,20 +49,8 @@ int amdtp_motu_set_parameters(struct amdtp_stream *s, unsigned int rate, unsigned int midi_ports, struct snd_motu_packet_format *formats) { - static const struct { - unsigned int quotient_ticks_per_event; - unsigned int remainder_ticks_per_event; - } params[] = { - [CIP_SFC_44100] = { 557, 123 }, - [CIP_SFC_48000] = { 512, 0 }, - [CIP_SFC_88200] = { 278, 282 }, - [CIP_SFC_96000] = { 256, 0 }, - [CIP_SFC_176400] = { 139, 141 }, - [CIP_SFC_192000] = { 128, 0 }, - }; struct amdtp_motu *p = s->protocol; unsigned int pcm_chunks, data_chunks, data_block_quadlets; - unsigned int delay; unsigned int mode; int i, err; @@ -111,18 +87,6 @@ int amdtp_motu_set_parameters(struct amdtp_stream *s, unsigned int rate, p->midi_db_count = 0; p->midi_db_interval = rate / MIDI_BYTES_PER_SECOND; - delay = TRANSFER_DELAY_TICKS; - - // For no-data or empty packets to adjust PCM sampling frequency. - delay += TICKS_PER_SECOND * s->syt_interval / rate; - - p->next_seconds = 0; - p->next_cycles = delay / TICKS_PER_CYCLE; - p->quotient_ticks_per_event = params[s->sfc].quotient_ticks_per_event; - p->remainder_ticks_per_event = params[s->sfc].remainder_ticks_per_event; - p->next_ticks = delay % TICKS_PER_CYCLE; - p->next_accumulated = 0; - return 0; } @@ -400,47 +364,26 @@ static unsigned int process_ir_ctx_payloads(struct amdtp_stream *s, return pcm_frames; } -static inline void compute_next_elapse_from_start(struct amdtp_motu *p) +static void write_sph(struct amdtp_motu_cache *cache, __be32 *buffer, unsigned int data_blocks, + unsigned int data_block_quadlets) { - p->next_accumulated += p->remainder_ticks_per_event; - if (p->next_accumulated >= 441) { - p->next_accumulated -= 441; - p->next_ticks++; - } - - p->next_ticks += p->quotient_ticks_per_event; - if (p->next_ticks >= TICKS_PER_CYCLE) { - p->next_ticks -= TICKS_PER_CYCLE; - p->next_cycles++; - } - - if (p->next_cycles >= CYCLES_PER_SECOND) { - p->next_cycles -= CYCLES_PER_SECOND; - p->next_seconds++; - } - - if (p->next_seconds >= IEEE1394_SEC_MODULUS) - p->next_seconds -= IEEE1394_SEC_MODULUS; -} - -static void write_sph(struct amdtp_stream *s, __be32 *buffer, unsigned int data_blocks, - const unsigned int rx_start_cycle) -{ - struct amdtp_motu *p = s->protocol; - unsigned int next_cycles; - unsigned int i; - u32 sph; + unsigned int *event_offsets = cache->event_offsets; + const unsigned int cache_size = cache->size; + unsigned int cache_head = cache->head; + unsigned int base_tick = cache->rx_cycle_count * TICKS_PER_CYCLE; + int i; for (i = 0; i < data_blocks; i++) { - next_cycles = (rx_start_cycle + p->next_cycles) % CYCLES_PER_SECOND; - sph = ((next_cycles << CIP_SPH_CYCLE_SHIFT) | p->next_ticks) & - (CIP_SPH_CYCLE_MASK | CIP_SPH_OFFSET_MASK); + unsigned int tick = (base_tick + event_offsets[cache_head]) % TICKS_PER_SECOND; + u32 sph = ((tick / TICKS_PER_CYCLE) << CIP_SPH_CYCLE_SHIFT) | (tick % TICKS_PER_CYCLE); *buffer = cpu_to_be32(sph); - compute_next_elapse_from_start(p); - - buffer += s->data_block_quadlets; + cache_head = (cache_head + 1) % cache_size; + buffer += data_block_quadlets; } + + cache->head = cache_head; + cache->rx_cycle_count = (cache->rx_cycle_count + 1) % CYCLES_PER_SECOND; } static unsigned int process_it_ctx_payloads(struct amdtp_stream *s, @@ -448,11 +391,13 @@ static unsigned int process_it_ctx_payloads(struct amdtp_stream *s, unsigned int packets, struct snd_pcm_substream *pcm) { - const unsigned int rx_start_cycle = s->domain->processing_cycle.rx_start; struct amdtp_motu *p = s->protocol; unsigned int pcm_frames = 0; int i; + if (p->cache->rx_cycle_count == UINT_MAX) + p->cache->rx_cycle_count = (s->domain->processing_cycle.rx_start % CYCLES_PER_SECOND); + // For data block processing. for (i = 0; i < packets; ++i) { const struct pkt_desc *desc = descs + i; @@ -471,7 +416,7 @@ static unsigned int process_it_ctx_payloads(struct amdtp_stream *s, // TODO: how to interact control messages between userspace? - write_sph(s, buf, data_blocks, rx_start_cycle); + write_sph(p->cache, buf, data_blocks, s->data_block_quadlets); } // For tracepoints. diff --git a/sound/firewire/motu/motu-stream.c b/sound/firewire/motu/motu-stream.c index 369002568b2d..43ff5be32b15 100644 --- a/sound/firewire/motu/motu-stream.c +++ b/sound/firewire/motu/motu-stream.c @@ -274,8 +274,13 @@ int snd_motu_stream_start_duplex(struct snd_motu *motu) motu->cache.tail = 0; motu->cache.tx_cycle_count = UINT_MAX; + motu->cache.head = 0; + motu->cache.rx_cycle_count = UINT_MAX; - err = amdtp_domain_start(&motu->domain, 0, false, false); + // NOTE: The device requires both of replay; the sequence of the number of data + // blocks per packet, and the sequence of source packet header per data block as + // presentation time. + err = amdtp_domain_start(&motu->domain, 0, true, false); if (err < 0) goto stop_streams; diff --git a/sound/firewire/motu/motu.h b/sound/firewire/motu/motu.h index 10ba87062e81..674e3dc4e45d 100644 --- a/sound/firewire/motu/motu.h +++ b/sound/firewire/motu/motu.h @@ -44,6 +44,8 @@ struct amdtp_motu_cache { unsigned int size; unsigned int tail; unsigned int tx_cycle_count; + unsigned int head; + unsigned int rx_cycle_count; }; struct snd_motu {