From patchwork Sun Jan 20 08:25:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takashi Sakamoto X-Patchwork-Id: 10772321 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A60816C2 for ; Sun, 20 Jan 2019 08:26:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 986A12ADF4 for ; Sun, 20 Jan 2019 08:26:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8B7C42ADF6; Sun, 20 Jan 2019 08:26:26 +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=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, 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 CDCAF2ADF4 for ; Sun, 20 Jan 2019 08:26:25 +0000 (UTC) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 1655C2673B4; Sun, 20 Jan 2019 09:26:18 +0100 (CET) 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 F3B76267350; Sun, 20 Jan 2019 09:26:13 +0100 (CET) Received: from mail-pg1-f193.google.com (mail-pg1-f193.google.com [209.85.215.193]) by alsa0.perex.cz (Postfix) with ESMTP id 19780267333 for ; Sun, 20 Jan 2019 09:26:10 +0100 (CET) Received: by mail-pg1-f193.google.com with SMTP id j10so8086906pga.1 for ; Sun, 20 Jan 2019 00:26:10 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=eFh4Dda2GEJWinWo/ECgMitaTSmtR5YV43tG4f0eVlg=; b=flMVkN5E+71R/dDt1+bAX8fLZVOK39piYFrSPAwN3bwairTlDEW7XlVdEG3lOAEqYH 7t7/nqXVVtk+z8xe6HdkbXhcn8YESSsmYbZqz9JPipiTSjZ/mEqurXOSl674vEqmb8m7 EG/ZoHS2r6w6XlJx2dosaqfym1P8ax8Dvd6AiJPsLpQ7DP+MV7qUDWvZ0EqaqDT6gnfc zPbhPmvy6juo2i5XlxrpgsLOaDG0oBde7WUnE2HxT++jz85LXAMRZ1SptrNroJHInTvV i6OhQrPPjbuxyRDMXUxZ/v9TEstZ8LvwoBttpRpB2p4bAICcWu5bl3ZKvEg9TyhqjQM7 ibJA== X-Gm-Message-State: AJcUukdmncBBFZtBifX6XFurbioW6e4VzgCrNef3XAsnRDRznUlyYFNK nFgB797mHqA3ctF29HojEaQ= X-Google-Smtp-Source: ALg8bN5WLfvCyNybEtSgyZUnXQl4jZACIsYM47uGTFXmKOwTcIpQhOouABXCgVpq8wgwn93dljHDkg== X-Received: by 2002:a63:9b11:: with SMTP id r17mr24131994pgd.416.1547972769903; Sun, 20 Jan 2019 00:26:09 -0800 (PST) Received: from localhost.localdomain ([2405:6580:9660:3200:489b:ac9:70e4:1515]) by smtp.gmail.com with ESMTPSA id z186sm12214046pfz.119.2019.01.20.00.26.08 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 20 Jan 2019 00:26:09 -0800 (PST) From: Takashi Sakamoto To: clemens@ladisch.de, tiwai@suse.de Date: Sun, 20 Jan 2019 17:25:45 +0900 Message-Id: <20190120082553.17347-2-o-takashi@sakamocchi.jp> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190120082553.17347-1-o-takashi@sakamocchi.jp> References: <20190120082553.17347-1-o-takashi@sakamocchi.jp> MIME-Version: 1.0 Cc: alsa-devel@alsa-project.org, ffado-devel@lists.sourceforge.net Subject: [alsa-devel] [PATCH 1/9] ALSA: fireface: rename protocol layer for former models 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 In a series of Fireface, later model supports different protocol from former models. This commit is a preparation to support both of protocols. Signed-off-by: Takashi Sakamoto --- sound/firewire/fireface/Makefile | 2 +- .../{ff-protocol-ff800.c => ff-protocol-former.c} | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) rename sound/firewire/fireface/{ff-protocol-ff800.c => ff-protocol-former.c} (94%) diff --git a/sound/firewire/fireface/Makefile b/sound/firewire/fireface/Makefile index 79a7d6d99d72..3fb586d32584 100644 --- a/sound/firewire/fireface/Makefile +++ b/sound/firewire/fireface/Makefile @@ -1,4 +1,4 @@ snd-fireface-objs := ff.o ff-transaction.o ff-midi.o ff-proc.o amdtp-ff.o \ ff-stream.o ff-pcm.o ff-hwdep.o ff-protocol-ff400.o \ - ff-protocol-ff800.o + ff-protocol-former.o obj-$(CONFIG_SND_FIREFACE) += snd-fireface.o diff --git a/sound/firewire/fireface/ff-protocol-ff800.c b/sound/firewire/fireface/ff-protocol-former.c similarity index 94% rename from sound/firewire/fireface/ff-protocol-ff800.c rename to sound/firewire/fireface/ff-protocol-former.c index 2acbf6039770..a383fd5fc879 100644 --- a/sound/firewire/fireface/ff-protocol-ff800.c +++ b/sound/firewire/fireface/ff-protocol-former.c @@ -1,10 +1,9 @@ -/* - * ff-protocol-ff800.c - a part of driver for RME Fireface series - * - * Copyright (c) 2018 Takashi Sakamoto - * - * Licensed under the terms of the GNU General Public License, version 2. - */ +// SPDX-License-Identifier: GPL-2.0 +// ff-protocol-former.c - a part of driver for RME Fireface series +// +// Copyright (c) 2019 Takashi Sakamoto +// +// Licensed under the terms of the GNU General Public License, version 2. #include From patchwork Sun Jan 20 08:25:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takashi Sakamoto X-Patchwork-Id: 10772323 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5FBA76C2 for ; Sun, 20 Jan 2019 08:26:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 520D82ADF4 for ; Sun, 20 Jan 2019 08:26:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 462A22ADF6; Sun, 20 Jan 2019 08:26:35 +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=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, 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 E079E2ADF4 for ; Sun, 20 Jan 2019 08:26:32 +0000 (UTC) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id A28102673FF; Sun, 20 Jan 2019 09:26:19 +0100 (CET) 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 B1432267343; Sun, 20 Jan 2019 09:26:15 +0100 (CET) Received: from mail-pl1-f194.google.com (mail-pl1-f194.google.com [209.85.214.194]) by alsa0.perex.cz (Postfix) with ESMTP id 753D5266A89 for ; Sun, 20 Jan 2019 09:26:13 +0100 (CET) Received: by mail-pl1-f194.google.com with SMTP id gn14so8299065plb.10 for ; Sun, 20 Jan 2019 00:26:13 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=j699y/kU4z68RfaRWLdAMKPMcgz8KKe6UCzuh7URZxM=; b=MP0VgGYGsuN6oH0Va0h3PJWT0jzSOnraxdmjsXV79u99vgGYKSDMgp46uUKO9OtTe+ OEtvKizBjlW7iz/sz7JdXtNz5x1JkWH+co3nD/t8B9mbiPOnWsYq9+FNNYD2/bqbuUam 6r+fHbgCoDtgJ3M9NcZ3sF/CNcxAiaUTuViPSgoOm1VuOS1mvgc4/wnvUtYkFyh1nLcE 7Ypu9lDl7Z/ZAyHI7NeQI+Q4C+mlwHqktt0pQyT/Pkeu7Vc3MfZSbXKK/+ziZpDRYFlL u7vtUVzWuHh7kVdDyKiRB2N9xVKl7QX44tn2nyFYDT1PZNznLnb6Wbxi85tI20r88/Df RDFA== X-Gm-Message-State: AJcUukduacthShoYys8UFlXaszYf2mtbTq2SO9Mrjzy80tEURaqu/WSo I3KbrtJFqt4sdgorLt8BOsY= X-Google-Smtp-Source: ALg8bN4iiCTeWpHpFirXyzbIHJ3ElNbi7HLD1LCrZ6xxVXieapDTPKT9wP84EcnSk3H12F5wJh9CMg== X-Received: by 2002:a17:902:d90d:: with SMTP id c13mr25640134plz.31.1547972771801; Sun, 20 Jan 2019 00:26:11 -0800 (PST) Received: from localhost.localdomain ([2405:6580:9660:3200:489b:ac9:70e4:1515]) by smtp.gmail.com with ESMTPSA id z186sm12214046pfz.119.2019.01.20.00.26.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 20 Jan 2019 00:26:11 -0800 (PST) From: Takashi Sakamoto To: clemens@ladisch.de, tiwai@suse.de Date: Sun, 20 Jan 2019 17:25:46 +0900 Message-Id: <20190120082553.17347-3-o-takashi@sakamocchi.jp> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190120082553.17347-1-o-takashi@sakamocchi.jp> References: <20190120082553.17347-1-o-takashi@sakamocchi.jp> MIME-Version: 1.0 Cc: alsa-devel@alsa-project.org, ffado-devel@lists.sourceforge.net Subject: [alsa-devel] [PATCH 2/9] ALSA: fireface: unify protocol layer for FF400/FF800 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 This commit moves codes for Fireface 400 to a file of former protocol. Signed-off-by: Takashi Sakamoto --- sound/firewire/fireface/Makefile | 3 +- sound/firewire/fireface/ff-protocol-ff400.c | 161 ------------------- sound/firewire/fireface/ff-protocol-former.c | 147 +++++++++++++++++ 3 files changed, 148 insertions(+), 163 deletions(-) delete mode 100644 sound/firewire/fireface/ff-protocol-ff400.c diff --git a/sound/firewire/fireface/Makefile b/sound/firewire/fireface/Makefile index 3fb586d32584..62eb78962b93 100644 --- a/sound/firewire/fireface/Makefile +++ b/sound/firewire/fireface/Makefile @@ -1,4 +1,3 @@ snd-fireface-objs := ff.o ff-transaction.o ff-midi.o ff-proc.o amdtp-ff.o \ - ff-stream.o ff-pcm.o ff-hwdep.o ff-protocol-ff400.o \ - ff-protocol-former.o + ff-stream.o ff-pcm.o ff-hwdep.o ff-protocol-former.o obj-$(CONFIG_SND_FIREFACE) += snd-fireface.o diff --git a/sound/firewire/fireface/ff-protocol-ff400.c b/sound/firewire/fireface/ff-protocol-ff400.c deleted file mode 100644 index 2280fab9b3c7..000000000000 --- a/sound/firewire/fireface/ff-protocol-ff400.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * ff-protocol-ff400.c - a part of driver for RME Fireface series - * - * Copyright (c) 2015-2017 Takashi Sakamoto - * - * Licensed under the terms of the GNU General Public License, version 2. - */ - -#include -#include "ff.h" - -#define FF400_STF 0x000080100500ull -#define FF400_RX_PACKET_FORMAT 0x000080100504ull -#define FF400_ISOC_COMM_START 0x000080100508ull -#define FF400_TX_PACKET_FORMAT 0x00008010050cull -#define FF400_ISOC_COMM_STOP 0x000080100510ull - -/* - * Fireface 400 manages isochronous channel number in 3 bit field. Therefore, - * we can allocate between 0 and 7 channel. - */ -static int keep_resources(struct snd_ff *ff, unsigned int rate) -{ - enum snd_ff_stream_mode mode; - int i; - int err; - - // Check whether the given value is supported or not. - for (i = 0; i < CIP_SFC_COUNT; i++) { - if (amdtp_rate_table[i] == rate) - break; - } - if (i >= CIP_SFC_COUNT) - return -EINVAL; - - err = snd_ff_stream_get_multiplier_mode(i, &mode); - if (err < 0) - return err; - - /* Keep resources for in-stream. */ - ff->tx_resources.channels_mask = 0x00000000000000ffuLL; - err = fw_iso_resources_allocate(&ff->tx_resources, - amdtp_stream_get_max_payload(&ff->tx_stream), - fw_parent_device(ff->unit)->max_speed); - if (err < 0) - return err; - - /* Keep resources for out-stream. */ - err = amdtp_ff_set_parameters(&ff->rx_stream, rate, - ff->spec->pcm_playback_channels[mode]); - if (err < 0) - return err; - ff->rx_resources.channels_mask = 0x00000000000000ffuLL; - err = fw_iso_resources_allocate(&ff->rx_resources, - amdtp_stream_get_max_payload(&ff->rx_stream), - fw_parent_device(ff->unit)->max_speed); - if (err < 0) - fw_iso_resources_free(&ff->tx_resources); - - return err; -} - -static int ff400_begin_session(struct snd_ff *ff, unsigned int rate) -{ - __le32 reg; - int err; - - err = keep_resources(ff, rate); - if (err < 0) - return err; - - /* Set the number of data blocks transferred in a second. */ - reg = cpu_to_le32(rate); - err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST, - FF400_STF, ®, sizeof(reg), 0); - if (err < 0) - return err; - - msleep(100); - - /* - * Set isochronous channel and the number of quadlets of received - * packets. - */ - reg = cpu_to_le32(((ff->rx_stream.data_block_quadlets << 3) << 8) | - ff->rx_resources.channel); - err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST, - FF400_RX_PACKET_FORMAT, ®, sizeof(reg), 0); - if (err < 0) - return err; - - /* - * Set isochronous channel and the number of quadlets of transmitted - * packet. - */ - /* TODO: investigate the purpose of this 0x80. */ - reg = cpu_to_le32((0x80 << 24) | - (ff->tx_resources.channel << 5) | - (ff->tx_stream.data_block_quadlets)); - err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST, - FF400_TX_PACKET_FORMAT, ®, sizeof(reg), 0); - if (err < 0) - return err; - - /* Allow to transmit packets. */ - reg = cpu_to_le32(0x00000001); - return snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST, - FF400_ISOC_COMM_START, ®, sizeof(reg), 0); -} - -static void ff400_finish_session(struct snd_ff *ff) -{ - __le32 reg; - - reg = cpu_to_le32(0x80000000); - snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST, - FF400_ISOC_COMM_STOP, ®, sizeof(reg), 0); -} - -static void ff400_handle_midi_msg(struct snd_ff *ff, __le32 *buf, size_t length) -{ - int i; - - for (i = 0; i < length / 4; i++) { - u32 quad = le32_to_cpu(buf[i]); - u8 byte; - unsigned int index; - struct snd_rawmidi_substream *substream; - - /* Message in first port. */ - /* - * This value may represent the index of this unit when the same - * units are on the same IEEE 1394 bus. This driver doesn't use - * it. - */ - index = (quad >> 8) & 0xff; - if (index > 0) { - substream = READ_ONCE(ff->tx_midi_substreams[0]); - if (substream != NULL) { - byte = quad & 0xff; - snd_rawmidi_receive(substream, &byte, 1); - } - } - - /* Message in second port. */ - index = (quad >> 24) & 0xff; - if (index > 0) { - substream = READ_ONCE(ff->tx_midi_substreams[1]); - if (substream != NULL) { - byte = (quad >> 16) & 0xff; - snd_rawmidi_receive(substream, &byte, 1); - } - } - } -} - -const struct snd_ff_protocol snd_ff_protocol_ff400 = { - .handle_midi_msg = ff400_handle_midi_msg, - .begin_session = ff400_begin_session, - .finish_session = ff400_finish_session, -}; diff --git a/sound/firewire/fireface/ff-protocol-former.c b/sound/firewire/fireface/ff-protocol-former.c index a383fd5fc879..ed1271a89484 100644 --- a/sound/firewire/fireface/ff-protocol-former.c +++ b/sound/firewire/fireface/ff-protocol-former.c @@ -140,3 +140,150 @@ const struct snd_ff_protocol snd_ff_protocol_ff800 = { .begin_session = ff800_begin_session, .finish_session = ff800_finish_session, }; + +#define FF400_STF 0x000080100500ull +#define FF400_RX_PACKET_FORMAT 0x000080100504ull +#define FF400_ISOC_COMM_START 0x000080100508ull +#define FF400_TX_PACKET_FORMAT 0x00008010050cull +#define FF400_ISOC_COMM_STOP 0x000080100510ull + +/* + * Fireface 400 manages isochronous channel number in 3 bit field. Therefore, + * we can allocate between 0 and 7 channel. + */ +static int keep_resources(struct snd_ff *ff, unsigned int rate) +{ + enum snd_ff_stream_mode mode; + int i; + int err; + + // Check whether the given value is supported or not. + for (i = 0; i < CIP_SFC_COUNT; i++) { + if (amdtp_rate_table[i] == rate) + break; + } + if (i >= CIP_SFC_COUNT) + return -EINVAL; + + err = snd_ff_stream_get_multiplier_mode(i, &mode); + if (err < 0) + return err; + + /* Keep resources for in-stream. */ + ff->tx_resources.channels_mask = 0x00000000000000ffuLL; + err = fw_iso_resources_allocate(&ff->tx_resources, + amdtp_stream_get_max_payload(&ff->tx_stream), + fw_parent_device(ff->unit)->max_speed); + if (err < 0) + return err; + + /* Keep resources for out-stream. */ + ff->rx_resources.channels_mask = 0x00000000000000ffuLL; + err = fw_iso_resources_allocate(&ff->rx_resources, + amdtp_stream_get_max_payload(&ff->rx_stream), + fw_parent_device(ff->unit)->max_speed); + if (err < 0) + fw_iso_resources_free(&ff->tx_resources); + + return err; +} + +static int ff400_begin_session(struct snd_ff *ff, unsigned int rate) +{ + __le32 reg; + int err; + + err = keep_resources(ff, rate); + if (err < 0) + return err; + + /* Set the number of data blocks transferred in a second. */ + reg = cpu_to_le32(rate); + err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST, + FF400_STF, ®, sizeof(reg), 0); + if (err < 0) + return err; + + msleep(100); + + /* + * Set isochronous channel and the number of quadlets of received + * packets. + */ + reg = cpu_to_le32(((ff->rx_stream.data_block_quadlets << 3) << 8) | + ff->rx_resources.channel); + err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST, + FF400_RX_PACKET_FORMAT, ®, sizeof(reg), 0); + if (err < 0) + return err; + + /* + * Set isochronous channel and the number of quadlets of transmitted + * packet. + */ + /* TODO: investigate the purpose of this 0x80. */ + reg = cpu_to_le32((0x80 << 24) | + (ff->tx_resources.channel << 5) | + (ff->tx_stream.data_block_quadlets)); + err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST, + FF400_TX_PACKET_FORMAT, ®, sizeof(reg), 0); + if (err < 0) + return err; + + /* Allow to transmit packets. */ + reg = cpu_to_le32(0x00000001); + return snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST, + FF400_ISOC_COMM_START, ®, sizeof(reg), 0); +} + +static void ff400_finish_session(struct snd_ff *ff) +{ + __le32 reg; + + reg = cpu_to_le32(0x80000000); + snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST, + FF400_ISOC_COMM_STOP, ®, sizeof(reg), 0); +} + +static void ff400_handle_midi_msg(struct snd_ff *ff, __le32 *buf, size_t length) +{ + int i; + + for (i = 0; i < length / 4; i++) { + u32 quad = le32_to_cpu(buf[i]); + u8 byte; + unsigned int index; + struct snd_rawmidi_substream *substream; + + /* Message in first port. */ + /* + * This value may represent the index of this unit when the same + * units are on the same IEEE 1394 bus. This driver doesn't use + * it. + */ + index = (quad >> 8) & 0xff; + if (index > 0) { + substream = READ_ONCE(ff->tx_midi_substreams[0]); + if (substream != NULL) { + byte = quad & 0xff; + snd_rawmidi_receive(substream, &byte, 1); + } + } + + /* Message in second port. */ + index = (quad >> 24) & 0xff; + if (index > 0) { + substream = READ_ONCE(ff->tx_midi_substreams[1]); + if (substream != NULL) { + byte = (quad >> 16) & 0xff; + snd_rawmidi_receive(substream, &byte, 1); + } + } + } +} + +const struct snd_ff_protocol snd_ff_protocol_ff400 = { + .handle_midi_msg = ff400_handle_midi_msg, + .begin_session = ff400_begin_session, + .finish_session = ff400_finish_session, +}; From patchwork Sun Jan 20 08:25:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takashi Sakamoto X-Patchwork-Id: 10772325 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CCD6E6C2 for ; Sun, 20 Jan 2019 08:26:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BE9C42ADF4 for ; Sun, 20 Jan 2019 08:26:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B0D462ADF6; Sun, 20 Jan 2019 08:26:41 +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=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, 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 107192ADF4 for ; Sun, 20 Jan 2019 08:26:41 +0000 (UTC) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 41589267418; Sun, 20 Jan 2019 09:26:23 +0100 (CET) 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 D30872673B8; Sun, 20 Jan 2019 09:26:16 +0100 (CET) Received: from mail-pl1-f193.google.com (mail-pl1-f193.google.com [209.85.214.193]) by alsa0.perex.cz (Postfix) with ESMTP id B7247266A89 for ; Sun, 20 Jan 2019 09:26:14 +0100 (CET) Received: by mail-pl1-f193.google.com with SMTP id u18so8307925plq.7 for ; Sun, 20 Jan 2019 00:26:14 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=X3iQ7DEbmj0vZn16+RJZKfqsimoR9oi29gwXgjzrtHA=; b=SerUBde0b+jQyT0LM6sEfMWoU2ihFDnuko8mQwkZ0wjIXzCMB+J8oNQYBAKZDSxdSs dRqNdYhK/6G5e/c8dlXmdv29ZpDN5ZP3eWrMl73pkeJEtARoDXfcCNKJc0nDVz3Kszva I6AFBr04/DYOEgGVuydaU0GbO/jxU9Ix0wgPt+f5QUOXd00f6hdqqFSru2SEs/SONI6I IfUqYAJDOrRN7sN+j3Cbt8fmIKjPuOP/I3WraIrPSfxw6RuybtthSm+TWbl9aUQLAMAb Jg2q0KcbmZ2re8XTYRtb+3Qh6mut050ELPdfsxGsAKJIdfCIlJrXoJ3HbPtT2V3YmQmk ErJg== X-Gm-Message-State: AJcUukeDYMRh+YTGL/ZsSurspsElltpIVyQ6PzwtpF4hL4JQy6k3h6+c Q+V8HJuqoP9agLJQpfvb1QU= X-Google-Smtp-Source: ALg8bN7rWApIEfuypiFy3fO8bzKrSTKn2XhWhoBJ1seTJvvImK2yMTtx5gByeH0K9KaM989LJtAX4A== X-Received: by 2002:a17:902:4681:: with SMTP id p1mr26123479pld.184.1547972773649; Sun, 20 Jan 2019 00:26:13 -0800 (PST) Received: from localhost.localdomain ([2405:6580:9660:3200:489b:ac9:70e4:1515]) by smtp.gmail.com with ESMTPSA id z186sm12214046pfz.119.2019.01.20.00.26.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 20 Jan 2019 00:26:13 -0800 (PST) From: Takashi Sakamoto To: clemens@ladisch.de, tiwai@suse.de Date: Sun, 20 Jan 2019 17:25:47 +0900 Message-Id: <20190120082553.17347-4-o-takashi@sakamocchi.jp> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190120082553.17347-1-o-takashi@sakamocchi.jp> References: <20190120082553.17347-1-o-takashi@sakamocchi.jp> MIME-Version: 1.0 Cc: alsa-devel@alsa-project.org, ffado-devel@lists.sourceforge.net Subject: [alsa-devel] [PATCH 3/9] ALSA: fireface: obsolete proc node to leave one node 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 In a series of Fireface, latter protocol has no way for drivers to retrieve current clock configuration. On the other hand, this driver has proc node for it. This commit removes a proc node to dump both clock configuration and synchronization status in one proc node. Signed-off-by: Takashi Sakamoto --- sound/firewire/fireface/ff-proc.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/sound/firewire/fireface/ff-proc.c b/sound/firewire/fireface/ff-proc.c index a0c550dabe9a..37f84b7fc432 100644 --- a/sound/firewire/fireface/ff-proc.c +++ b/sound/firewire/fireface/ff-proc.c @@ -8,10 +8,8 @@ #include "./ff.h" -static void proc_dump_clock_config(struct snd_info_entry *entry, - struct snd_info_buffer *buffer) +static void dump_clock_config(struct snd_ff *ff, struct snd_info_buffer *buffer) { - struct snd_ff *ff = entry->private_data; __le32 reg; u32 data; unsigned int rate; @@ -87,10 +85,8 @@ static void proc_dump_clock_config(struct snd_info_entry *entry, snd_iprintf(buffer, "Sync to clock source: %s\n", src); } -static void proc_dump_sync_status(struct snd_info_entry *entry, - struct snd_info_buffer *buffer) +static void dump_sync_status(struct snd_ff *ff, struct snd_info_buffer *buffer) { - struct snd_ff *ff = entry->private_data; __le32 reg; u32 data; int err; @@ -213,6 +209,15 @@ static void proc_dump_sync_status(struct snd_info_entry *entry, snd_iprintf(buffer, "%d\n", (data & 0x3ff) * 250); } +static void proc_dump_status(struct snd_info_entry *entry, + struct snd_info_buffer *buffer) +{ + struct snd_ff *ff = entry->private_data; + + dump_clock_config(ff, buffer); + dump_sync_status(ff, buffer); +} + static void add_node(struct snd_ff *ff, struct snd_info_entry *root, const char *name, void (*op)(struct snd_info_entry *e, @@ -247,6 +252,5 @@ void snd_ff_proc_init(struct snd_ff *ff) return; } - add_node(ff, root, "clock-config", proc_dump_clock_config); - add_node(ff, root, "sync-status", proc_dump_sync_status); + add_node(ff, root, "status", proc_dump_status); } From patchwork Sun Jan 20 08:25:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takashi Sakamoto X-Patchwork-Id: 10772327 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 69AD46C2 for ; Sun, 20 Jan 2019 08:26:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5BD4A2ADF4 for ; Sun, 20 Jan 2019 08:26:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4D65E2ADF6; Sun, 20 Jan 2019 08:26:50 +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=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, 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 3CD592ADF4 for ; Sun, 20 Jan 2019 08:26:49 +0000 (UTC) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id CD564267420; Sun, 20 Jan 2019 09:26:24 +0100 (CET) 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 ACF72267418; Sun, 20 Jan 2019 09:26:19 +0100 (CET) Received: from mail-pf1-f196.google.com (mail-pf1-f196.google.com [209.85.210.196]) by alsa0.perex.cz (Postfix) with ESMTP id 369B22673E2 for ; Sun, 20 Jan 2019 09:26:16 +0100 (CET) Received: by mail-pf1-f196.google.com with SMTP id c73so8675989pfe.13 for ; Sun, 20 Jan 2019 00:26:16 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=amKaFjmaJBtKk9nw06yms3v8+nYnTxV3d7xfN23EXZ4=; b=PBeaHNpwNuRU8dAcPKzJD/7SHtWgEFDvAPY25VJ5E1DwxZdolkAcG2/fIPz1w3aIin lTJCQMNKGEWqfg9S3yhV9zmabgExV6dO8U6nCHTlXe2eUdYR0hVeFTrizm/mmxVDNaRS tBjqfGwO80TOxVZcUdoLeDQjLT9VUD+YqZw9Zg997nju9G1mfnnBvtfaFzHGWYM5M0aY BWmKXG0p/tVEZCoJBSFKZeHS11rthRXP7gUrDUuUuZJIps6cnqEUYyDGUbPggUSEsYKQ iPNmWJ5pAaqXtT16zx7utuWz+ZtYX1k3sd3Vtn2RtllWdaRuNGi4zNNRyQ679Wm1taGu CVfQ== X-Gm-Message-State: AJcUukdRwEMiN59Hn/j3GV+WDNZl2AAxxOgAICCa4RLu9+Pps7LwIG8f 5YMdemSJl+d1jET1o/ZbMrY= X-Google-Smtp-Source: ALg8bN4aFtSdZJ/VlkKy3EN7vWb5b/6EPQIFK81TRSNKfS9VGC0IR5V547y96fx5uZ/8f9s92117aw== X-Received: by 2002:a62:28c9:: with SMTP id o192mr26152650pfo.57.1547972775500; Sun, 20 Jan 2019 00:26:15 -0800 (PST) Received: from localhost.localdomain ([2405:6580:9660:3200:489b:ac9:70e4:1515]) by smtp.gmail.com with ESMTPSA id z186sm12214046pfz.119.2019.01.20.00.26.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 20 Jan 2019 00:26:14 -0800 (PST) From: Takashi Sakamoto To: clemens@ladisch.de, tiwai@suse.de Date: Sun, 20 Jan 2019 17:25:48 +0900 Message-Id: <20190120082553.17347-5-o-takashi@sakamocchi.jp> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190120082553.17347-1-o-takashi@sakamocchi.jp> References: <20190120082553.17347-1-o-takashi@sakamocchi.jp> MIME-Version: 1.0 Cc: alsa-devel@alsa-project.org, ffado-devel@lists.sourceforge.net Subject: [alsa-devel] [PATCH 4/9] ALSA: fireface: add protocol-dependent operation to dump status 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 This commit adds a member for a callback function to dump status and move existing code to former protocol. Signed-off-by: Takashi Sakamoto --- sound/firewire/fireface/ff-proc.c | 204 +----------------- sound/firewire/fireface/ff-protocol-former.c | 212 +++++++++++++++++++ sound/firewire/fireface/ff.h | 2 +- 3 files changed, 214 insertions(+), 204 deletions(-) diff --git a/sound/firewire/fireface/ff-proc.c b/sound/firewire/fireface/ff-proc.c index 37f84b7fc432..8a7cfb6ccce6 100644 --- a/sound/firewire/fireface/ff-proc.c +++ b/sound/firewire/fireface/ff-proc.c @@ -8,214 +8,12 @@ #include "./ff.h" -static void dump_clock_config(struct snd_ff *ff, struct snd_info_buffer *buffer) -{ - __le32 reg; - u32 data; - unsigned int rate; - const char *src; - int err; - - err = snd_fw_transaction(ff->unit, TCODE_READ_BLOCK_REQUEST, - SND_FF_REG_CLOCK_CONFIG, ®, sizeof(reg), 0); - if (err < 0) - return; - - data = le32_to_cpu(reg); - - snd_iprintf(buffer, "Output S/PDIF format: %s (Emphasis: %s)\n", - (data & 0x20) ? "Professional" : "Consumer", - (data & 0x40) ? "on" : "off"); - - snd_iprintf(buffer, "Optical output interface format: %s\n", - ((data >> 8) & 0x01) ? "S/PDIF" : "ADAT"); - - snd_iprintf(buffer, "Word output single speed: %s\n", - ((data >> 8) & 0x20) ? "on" : "off"); - - snd_iprintf(buffer, "S/PDIF input interface: %s\n", - ((data >> 8) & 0x02) ? "Optical" : "Coaxial"); - - switch ((data >> 1) & 0x03) { - case 0x01: - rate = 32000; - break; - case 0x00: - rate = 44100; - break; - case 0x03: - rate = 48000; - break; - case 0x02: - default: - return; - } - - if (data & 0x08) - rate *= 2; - else if (data & 0x10) - rate *= 4; - - snd_iprintf(buffer, "Sampling rate: %d\n", rate); - - if (data & 0x01) { - src = "Internal"; - } else { - switch ((data >> 10) & 0x07) { - case 0x00: - src = "ADAT1"; - break; - case 0x01: - src = "ADAT2"; - break; - case 0x03: - src = "S/PDIF"; - break; - case 0x04: - src = "Word"; - break; - case 0x05: - src = "LTC"; - break; - default: - return; - } - } - - snd_iprintf(buffer, "Sync to clock source: %s\n", src); -} - -static void dump_sync_status(struct snd_ff *ff, struct snd_info_buffer *buffer) -{ - __le32 reg; - u32 data; - int err; - - err = snd_fw_transaction(ff->unit, TCODE_READ_QUADLET_REQUEST, - SND_FF_REG_SYNC_STATUS, ®, sizeof(reg), 0); - if (err < 0) - return; - - data = le32_to_cpu(reg); - - snd_iprintf(buffer, "External source detection:\n"); - - snd_iprintf(buffer, "Word Clock:"); - if ((data >> 24) & 0x20) { - if ((data >> 24) & 0x40) - snd_iprintf(buffer, "sync\n"); - else - snd_iprintf(buffer, "lock\n"); - } else { - snd_iprintf(buffer, "none\n"); - } - - snd_iprintf(buffer, "S/PDIF:"); - if ((data >> 16) & 0x10) { - if ((data >> 16) & 0x04) - snd_iprintf(buffer, "sync\n"); - else - snd_iprintf(buffer, "lock\n"); - } else { - snd_iprintf(buffer, "none\n"); - } - - snd_iprintf(buffer, "ADAT1:"); - if ((data >> 8) & 0x04) { - if ((data >> 8) & 0x10) - snd_iprintf(buffer, "sync\n"); - else - snd_iprintf(buffer, "lock\n"); - } else { - snd_iprintf(buffer, "none\n"); - } - - snd_iprintf(buffer, "ADAT2:"); - if ((data >> 8) & 0x08) { - if ((data >> 8) & 0x20) - snd_iprintf(buffer, "sync\n"); - else - snd_iprintf(buffer, "lock\n"); - } else { - snd_iprintf(buffer, "none\n"); - } - - snd_iprintf(buffer, "\nUsed external source:\n"); - - if (((data >> 22) & 0x07) == 0x07) { - snd_iprintf(buffer, "None\n"); - } else { - switch ((data >> 22) & 0x07) { - case 0x00: - snd_iprintf(buffer, "ADAT1:"); - break; - case 0x01: - snd_iprintf(buffer, "ADAT2:"); - break; - case 0x03: - snd_iprintf(buffer, "S/PDIF:"); - break; - case 0x04: - snd_iprintf(buffer, "Word:"); - break; - case 0x07: - snd_iprintf(buffer, "Nothing:"); - break; - case 0x02: - case 0x05: - case 0x06: - default: - snd_iprintf(buffer, "unknown:"); - break; - } - - if ((data >> 25) & 0x07) { - switch ((data >> 25) & 0x07) { - case 0x01: - snd_iprintf(buffer, "32000\n"); - break; - case 0x02: - snd_iprintf(buffer, "44100\n"); - break; - case 0x03: - snd_iprintf(buffer, "48000\n"); - break; - case 0x04: - snd_iprintf(buffer, "64000\n"); - break; - case 0x05: - snd_iprintf(buffer, "88200\n"); - break; - case 0x06: - snd_iprintf(buffer, "96000\n"); - break; - case 0x07: - snd_iprintf(buffer, "128000\n"); - break; - case 0x08: - snd_iprintf(buffer, "176400\n"); - break; - case 0x09: - snd_iprintf(buffer, "192000\n"); - break; - case 0x00: - snd_iprintf(buffer, "unknown\n"); - break; - } - } - } - - snd_iprintf(buffer, "Multiplied:"); - snd_iprintf(buffer, "%d\n", (data & 0x3ff) * 250); -} - static void proc_dump_status(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { struct snd_ff *ff = entry->private_data; - dump_clock_config(ff, buffer); - dump_sync_status(ff, buffer); + ff->spec->protocol->dump_status(ff, buffer); } static void add_node(struct snd_ff *ff, struct snd_info_entry *root, diff --git a/sound/firewire/fireface/ff-protocol-former.c b/sound/firewire/fireface/ff-protocol-former.c index ed1271a89484..5f97e7fc7281 100644 --- a/sound/firewire/fireface/ff-protocol-former.c +++ b/sound/firewire/fireface/ff-protocol-former.c @@ -9,6 +9,216 @@ #include "ff.h" +#define FORMER_REG_SYNC_STATUS 0x0000801c0000ull + +static void dump_clock_config(struct snd_ff *ff, struct snd_info_buffer *buffer) +{ + __le32 reg; + u32 data; + unsigned int rate; + const char *src; + int err; + + err = snd_fw_transaction(ff->unit, TCODE_READ_BLOCK_REQUEST, + SND_FF_REG_CLOCK_CONFIG, ®, sizeof(reg), 0); + if (err < 0) + return; + + data = le32_to_cpu(reg); + + snd_iprintf(buffer, "Output S/PDIF format: %s (Emphasis: %s)\n", + (data & 0x20) ? "Professional" : "Consumer", + (data & 0x40) ? "on" : "off"); + + snd_iprintf(buffer, "Optical output interface format: %s\n", + ((data >> 8) & 0x01) ? "S/PDIF" : "ADAT"); + + snd_iprintf(buffer, "Word output single speed: %s\n", + ((data >> 8) & 0x20) ? "on" : "off"); + + snd_iprintf(buffer, "S/PDIF input interface: %s\n", + ((data >> 8) & 0x02) ? "Optical" : "Coaxial"); + + switch ((data >> 1) & 0x03) { + case 0x01: + rate = 32000; + break; + case 0x00: + rate = 44100; + break; + case 0x03: + rate = 48000; + break; + case 0x02: + default: + return; + } + + if (data & 0x08) + rate *= 2; + else if (data & 0x10) + rate *= 4; + + snd_iprintf(buffer, "Sampling rate: %d\n", rate); + + if (data & 0x01) { + src = "Internal"; + } else { + switch ((data >> 10) & 0x07) { + case 0x00: + src = "ADAT1"; + break; + case 0x01: + src = "ADAT2"; + break; + case 0x03: + src = "S/PDIF"; + break; + case 0x04: + src = "Word"; + break; + case 0x05: + src = "LTC"; + break; + default: + return; + } + } + + snd_iprintf(buffer, "Sync to clock source: %s\n", src); +} + +static void dump_sync_status(struct snd_ff *ff, struct snd_info_buffer *buffer) +{ + __le32 reg; + u32 data; + int err; + + err = snd_fw_transaction(ff->unit, TCODE_READ_QUADLET_REQUEST, + FORMER_REG_SYNC_STATUS, ®, sizeof(reg), 0); + if (err < 0) + return; + + data = le32_to_cpu(reg); + + snd_iprintf(buffer, "External source detection:\n"); + + snd_iprintf(buffer, "Word Clock:"); + if ((data >> 24) & 0x20) { + if ((data >> 24) & 0x40) + snd_iprintf(buffer, "sync\n"); + else + snd_iprintf(buffer, "lock\n"); + } else { + snd_iprintf(buffer, "none\n"); + } + + snd_iprintf(buffer, "S/PDIF:"); + if ((data >> 16) & 0x10) { + if ((data >> 16) & 0x04) + snd_iprintf(buffer, "sync\n"); + else + snd_iprintf(buffer, "lock\n"); + } else { + snd_iprintf(buffer, "none\n"); + } + + snd_iprintf(buffer, "ADAT1:"); + if ((data >> 8) & 0x04) { + if ((data >> 8) & 0x10) + snd_iprintf(buffer, "sync\n"); + else + snd_iprintf(buffer, "lock\n"); + } else { + snd_iprintf(buffer, "none\n"); + } + + snd_iprintf(buffer, "ADAT2:"); + if ((data >> 8) & 0x08) { + if ((data >> 8) & 0x20) + snd_iprintf(buffer, "sync\n"); + else + snd_iprintf(buffer, "lock\n"); + } else { + snd_iprintf(buffer, "none\n"); + } + + snd_iprintf(buffer, "\nUsed external source:\n"); + + if (((data >> 22) & 0x07) == 0x07) { + snd_iprintf(buffer, "None\n"); + } else { + switch ((data >> 22) & 0x07) { + case 0x00: + snd_iprintf(buffer, "ADAT1:"); + break; + case 0x01: + snd_iprintf(buffer, "ADAT2:"); + break; + case 0x03: + snd_iprintf(buffer, "S/PDIF:"); + break; + case 0x04: + snd_iprintf(buffer, "Word:"); + break; + case 0x07: + snd_iprintf(buffer, "Nothing:"); + break; + case 0x02: + case 0x05: + case 0x06: + default: + snd_iprintf(buffer, "unknown:"); + break; + } + + if ((data >> 25) & 0x07) { + switch ((data >> 25) & 0x07) { + case 0x01: + snd_iprintf(buffer, "32000\n"); + break; + case 0x02: + snd_iprintf(buffer, "44100\n"); + break; + case 0x03: + snd_iprintf(buffer, "48000\n"); + break; + case 0x04: + snd_iprintf(buffer, "64000\n"); + break; + case 0x05: + snd_iprintf(buffer, "88200\n"); + break; + case 0x06: + snd_iprintf(buffer, "96000\n"); + break; + case 0x07: + snd_iprintf(buffer, "128000\n"); + break; + case 0x08: + snd_iprintf(buffer, "176400\n"); + break; + case 0x09: + snd_iprintf(buffer, "192000\n"); + break; + case 0x00: + snd_iprintf(buffer, "unknown\n"); + break; + } + } + } + + snd_iprintf(buffer, "Multiplied:"); + snd_iprintf(buffer, "%d\n", (data & 0x3ff) * 250); +} + +static void former_dump_status(struct snd_ff *ff, + struct snd_info_buffer *buffer) +{ + dump_clock_config(ff, buffer); + dump_sync_status(ff, buffer); +} + #define FF800_STF 0x0000fc88f000 #define FF800_RX_PACKET_FORMAT 0x0000fc88f004 #define FF800_ALLOC_TX_STREAM 0x0000fc88f008 @@ -139,6 +349,7 @@ const struct snd_ff_protocol snd_ff_protocol_ff800 = { .handle_midi_msg = ff800_handle_midi_msg, .begin_session = ff800_begin_session, .finish_session = ff800_finish_session, + .dump_status = former_dump_status, }; #define FF400_STF 0x000080100500ull @@ -286,4 +497,5 @@ const struct snd_ff_protocol snd_ff_protocol_ff400 = { .handle_midi_msg = ff400_handle_midi_msg, .begin_session = ff400_begin_session, .finish_session = ff400_finish_session, + .dump_status = former_dump_status, }; diff --git a/sound/firewire/fireface/ff.h b/sound/firewire/fireface/ff.h index 7dfc7745a914..3f22b8d84e36 100644 --- a/sound/firewire/fireface/ff.h +++ b/sound/firewire/fireface/ff.h @@ -35,7 +35,6 @@ #define SND_FF_IN_MIDI_PORTS 2 #define SND_FF_OUT_MIDI_PORTS 2 -#define SND_FF_REG_SYNC_STATUS 0x0000801c0000ull /* For block write request. */ #define SND_FF_REG_FETCH_PCM_FRAMES 0x0000801c0000ull #define SND_FF_REG_CLOCK_CONFIG 0x0000801c0004ull @@ -111,6 +110,7 @@ struct snd_ff_protocol { void (*handle_midi_msg)(struct snd_ff *ff, __le32 *buf, size_t length); int (*begin_session)(struct snd_ff *ff, unsigned int rate); void (*finish_session)(struct snd_ff *ff); + void (*dump_status)(struct snd_ff *ff, struct snd_info_buffer *buffer); }; extern const struct snd_ff_protocol snd_ff_protocol_ff800; From patchwork Sun Jan 20 08:25:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takashi Sakamoto X-Patchwork-Id: 10772329 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0FCED746 for ; Sun, 20 Jan 2019 08:26:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 01FAB2ADF3 for ; Sun, 20 Jan 2019 08:26:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E80722ADF5; Sun, 20 Jan 2019 08:26:57 +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=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, 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 2A31A2ADF3 for ; Sun, 20 Jan 2019 08:26:57 +0000 (UTC) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 49A5626742B; Sun, 20 Jan 2019 09:26:26 +0100 (CET) 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 959BE267419; Sun, 20 Jan 2019 09:26:20 +0100 (CET) Received: from mail-pl1-f193.google.com (mail-pl1-f193.google.com [209.85.214.193]) by alsa0.perex.cz (Postfix) with ESMTP id 431C52673F9 for ; Sun, 20 Jan 2019 09:26:18 +0100 (CET) Received: by mail-pl1-f193.google.com with SMTP id u18so8307955plq.7 for ; Sun, 20 Jan 2019 00:26:18 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=KoGuG7jJxRmtVH7DwfIcdI3YWMknBt41iUL/QSrNpsY=; b=mYeYQHqb/EguXFalTcW1SJcYOhXOatrtiUL5SThzsOplw4b/UaSpjaWa86FOWXSPoJ cy3TgewEEwYnpI7yXcwLbWvi+lR2degFeMsfL7qflBlkeqf5hXScDyf8U0aNxLCs3kBR b4ANZ2CfAxuDVov5rFe6+e9U4yaR0av26bFDTyL0VeJqL4BzxRA0c074rZ0WZ2W5ofg5 8M0Q134R0lAzvmcg7yAg2qYgGyjVSjh2+VkiZ7bJLnRXXrBOyw0nw4z7skEM0hRTqKwb 2t1EeuYqH7O7liY4eRAk9AWO4GWegtXDLdzOJj57pTmwVrNZlUFODDIK2MA6K4larTv/ kUUQ== X-Gm-Message-State: AJcUukd2hBFkBfj+a/Y7g9QT7eboLH8hAvbCnkZSSpAYnT5kJ45yabWF 8cGgcFqmJ7gC2/XdhzHgtmo= X-Google-Smtp-Source: ALg8bN4ENVxnVIbcKs5dtciqqqxTDvINwVz9IOZpFPuKMyt43wVvfroXvilmeOPo/yUpBN8JfvIKUg== X-Received: by 2002:a17:902:365:: with SMTP id 92mr24423649pld.327.1547972777347; Sun, 20 Jan 2019 00:26:17 -0800 (PST) Received: from localhost.localdomain ([2405:6580:9660:3200:489b:ac9:70e4:1515]) by smtp.gmail.com with ESMTPSA id z186sm12214046pfz.119.2019.01.20.00.26.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 20 Jan 2019 00:26:16 -0800 (PST) From: Takashi Sakamoto To: clemens@ladisch.de, tiwai@suse.de Date: Sun, 20 Jan 2019 17:25:49 +0900 Message-Id: <20190120082553.17347-6-o-takashi@sakamocchi.jp> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190120082553.17347-1-o-takashi@sakamocchi.jp> References: <20190120082553.17347-1-o-takashi@sakamocchi.jp> MIME-Version: 1.0 Cc: alsa-devel@alsa-project.org, ffado-devel@lists.sourceforge.net Subject: [alsa-devel] [PATCH 5/9] ALSA: fireface: add protocol-dependent operation to switch mode to fetch PCM frame 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 This commit adds a member for a callback function to switch frame fetching mode to former protocol. Signed-off-by: Takashi Sakamoto --- sound/firewire/fireface/ff-protocol-former.c | 38 ++++++++++++++++++++ sound/firewire/fireface/ff-stream.c | 38 ++------------------ sound/firewire/fireface/ff.h | 3 +- 3 files changed, 41 insertions(+), 38 deletions(-) diff --git a/sound/firewire/fireface/ff-protocol-former.c b/sound/firewire/fireface/ff-protocol-former.c index 5f97e7fc7281..279bd032acf0 100644 --- a/sound/firewire/fireface/ff-protocol-former.c +++ b/sound/firewire/fireface/ff-protocol-former.c @@ -10,6 +10,42 @@ #include "ff.h" #define FORMER_REG_SYNC_STATUS 0x0000801c0000ull +/* For block write request. */ +#define FORMER_REG_FETCH_PCM_FRAMES 0x0000801c0000ull + +static int former_switch_fetching_mode(struct snd_ff *ff, bool enable) +{ + unsigned int count; + __le32 *reg; + int i; + int err; + + count = 0; + for (i = 0; i < SND_FF_STREAM_MODE_COUNT; ++i) + count = max(count, ff->spec->pcm_playback_channels[i]); + + reg = kcalloc(count, sizeof(__le32), GFP_KERNEL); + if (!reg) + return -ENOMEM; + + if (!enable) { + /* + * Each quadlet is corresponding to data channels in a data + * blocks in reverse order. Precisely, quadlets for available + * data channels should be enabled. Here, I take second best + * to fetch PCM frames from all of data channels regardless of + * stf. + */ + for (i = 0; i < count; ++i) + reg[i] = cpu_to_le32(0x00000001); + } + + err = snd_fw_transaction(ff->unit, TCODE_WRITE_BLOCK_REQUEST, + FORMER_REG_FETCH_PCM_FRAMES, reg, + sizeof(__le32) * count, 0); + kfree(reg); + return err; +} static void dump_clock_config(struct snd_ff *ff, struct snd_info_buffer *buffer) { @@ -347,6 +383,7 @@ static void ff800_handle_midi_msg(struct snd_ff *ff, __le32 *buf, size_t length) const struct snd_ff_protocol snd_ff_protocol_ff800 = { .handle_midi_msg = ff800_handle_midi_msg, + .switch_fetching_mode = former_switch_fetching_mode, .begin_session = ff800_begin_session, .finish_session = ff800_finish_session, .dump_status = former_dump_status, @@ -495,6 +532,7 @@ static void ff400_handle_midi_msg(struct snd_ff *ff, __le32 *buf, size_t length) const struct snd_ff_protocol snd_ff_protocol_ff400 = { .handle_midi_msg = ff400_handle_midi_msg, + .switch_fetching_mode = former_switch_fetching_mode, .begin_session = ff400_begin_session, .finish_session = ff400_finish_session, .dump_status = former_dump_status, diff --git a/sound/firewire/fireface/ff-stream.c b/sound/firewire/fireface/ff-stream.c index a490e4553721..43e1e2679798 100644 --- a/sound/firewire/fireface/ff-stream.c +++ b/sound/firewire/fireface/ff-stream.c @@ -37,44 +37,10 @@ static void release_resources(struct snd_ff *ff) fw_iso_resources_free(&ff->rx_resources); } -static int switch_fetching_mode(struct snd_ff *ff, bool enable) -{ - unsigned int count; - __le32 *reg; - int i; - int err; - - count = 0; - for (i = 0; i < SND_FF_STREAM_MODE_COUNT; ++i) - count = max(count, ff->spec->pcm_playback_channels[i]); - - reg = kcalloc(count, sizeof(__le32), GFP_KERNEL); - if (!reg) - return -ENOMEM; - - if (!enable) { - /* - * Each quadlet is corresponding to data channels in a data - * blocks in reverse order. Precisely, quadlets for available - * data channels should be enabled. Here, I take second best - * to fetch PCM frames from all of data channels regardless of - * stf. - */ - for (i = 0; i < count; ++i) - reg[i] = cpu_to_le32(0x00000001); - } - - err = snd_fw_transaction(ff->unit, TCODE_WRITE_BLOCK_REQUEST, - SND_FF_REG_FETCH_PCM_FRAMES, reg, - sizeof(__le32) * count, 0); - kfree(reg); - return err; -} - static inline void finish_session(struct snd_ff *ff) { ff->spec->protocol->finish_session(ff); - switch_fetching_mode(ff, false); + ff->spec->protocol->switch_fetching_mode(ff, false); } static int init_stream(struct snd_ff *ff, enum amdtp_stream_direction dir) @@ -206,7 +172,7 @@ int snd_ff_stream_start_duplex(struct snd_ff *ff, unsigned int rate) goto error; } - err = switch_fetching_mode(ff, true); + err = ff->spec->protocol->switch_fetching_mode(ff, true); if (err < 0) goto error; } diff --git a/sound/firewire/fireface/ff.h b/sound/firewire/fireface/ff.h index 3f22b8d84e36..29f55518bf85 100644 --- a/sound/firewire/fireface/ff.h +++ b/sound/firewire/fireface/ff.h @@ -35,8 +35,6 @@ #define SND_FF_IN_MIDI_PORTS 2 #define SND_FF_OUT_MIDI_PORTS 2 -/* For block write request. */ -#define SND_FF_REG_FETCH_PCM_FRAMES 0x0000801c0000ull #define SND_FF_REG_CLOCK_CONFIG 0x0000801c0004ull enum snd_ff_stream_mode { @@ -108,6 +106,7 @@ enum snd_ff_clock_src { struct snd_ff_protocol { void (*handle_midi_msg)(struct snd_ff *ff, __le32 *buf, size_t length); + int (*switch_fetching_mode)(struct snd_ff *ff, bool enable); int (*begin_session)(struct snd_ff *ff, unsigned int rate); void (*finish_session)(struct snd_ff *ff); void (*dump_status)(struct snd_ff *ff, struct snd_info_buffer *buffer); From patchwork Sun Jan 20 08:25:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takashi Sakamoto X-Patchwork-Id: 10772331 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7A125746 for ; Sun, 20 Jan 2019 08:27:07 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6B9E82ADF4 for ; Sun, 20 Jan 2019 08:27:07 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5D9D22ADF5; Sun, 20 Jan 2019 08:27:07 +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=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, 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 7A4462ADF6 for ; Sun, 20 Jan 2019 08:27:06 +0000 (UTC) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id F046B267453; Sun, 20 Jan 2019 09:26:29 +0100 (CET) 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 1BDB02673B8; Sun, 20 Jan 2019 09:26:23 +0100 (CET) Received: from mail-pl1-f194.google.com (mail-pl1-f194.google.com [209.85.214.194]) by alsa0.perex.cz (Postfix) with ESMTP id 53341267419 for ; Sun, 20 Jan 2019 09:26:20 +0100 (CET) Received: by mail-pl1-f194.google.com with SMTP id a14so8289199plm.12 for ; Sun, 20 Jan 2019 00:26:19 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=0IPyc4bKcGsBzs3Co3ctGdbD7tizs8kgNBxRoX2Zs4Y=; b=JSRnVmZ9O7mu8MaZ1Vyw2C0a5kjW1wp80Wp4qN48StqYUbCNNxn3N32ZC/IlfAoUec OLQ5ceLbCxaqcI7V6VZPuNXs2Vozun5RWqexFQoG/D+XidtWzxkuHfHSSBFzdbzA/shw JF4HIxDz6kZ57AjLOIuFKt1RWCKCp6Yl2j5r5suGbzN9zZlDBMOV4HQjEuOopVa0YRmC 5iwjtVC9WGbgx5RrgSzb2Rkh0irWUgxxoYxlkGGF6pG/rx/Kag7RUCElLitrsXNLBo8/ Fv+WfoYXuxdj3R12ai3eEoxlD+HwGeZ9WCsV2WM/ao91dTPhe7LtUeVUgH2UBQdgw7gU VAfw== X-Gm-Message-State: AJcUukeWL3cMtEeIWSet6CO32U/TZh6OM0Ln74dmQeaSdR2nR1Hct/vo 3H4UDZJOOp9gWK8MHfSSXlo= X-Google-Smtp-Source: ALg8bN7dVkgK1fnLUE38IdlNH1hydjZgyNM39A+q19hoJP2PzOrWfi/J8oSe7IxhJ1WP8CqKmG/MGg== X-Received: by 2002:a17:902:8b88:: with SMTP id ay8mr25793682plb.55.1547972779192; Sun, 20 Jan 2019 00:26:19 -0800 (PST) Received: from localhost.localdomain ([2405:6580:9660:3200:489b:ac9:70e4:1515]) by smtp.gmail.com with ESMTPSA id z186sm12214046pfz.119.2019.01.20.00.26.17 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 20 Jan 2019 00:26:18 -0800 (PST) From: Takashi Sakamoto To: clemens@ladisch.de, tiwai@suse.de Date: Sun, 20 Jan 2019 17:25:50 +0900 Message-Id: <20190120082553.17347-7-o-takashi@sakamocchi.jp> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190120082553.17347-1-o-takashi@sakamocchi.jp> References: <20190120082553.17347-1-o-takashi@sakamocchi.jp> MIME-Version: 1.0 Cc: alsa-devel@alsa-project.org, ffado-devel@lists.sourceforge.net Subject: [alsa-devel] [PATCH 6/9] ALSA: fireface: add protocol-dependent operation to get clock status 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 This commit adds a member for a callback function to get clock status to former protocol. Signed-off-by: Takashi Sakamoto --- sound/firewire/fireface/ff-pcm.c | 2 +- sound/firewire/fireface/ff-protocol-former.c | 68 +++++++++++++++++++- sound/firewire/fireface/ff-stream.c | 2 +- sound/firewire/fireface/ff-transaction.c | 63 ------------------ sound/firewire/fireface/ff.h | 6 +- 5 files changed, 71 insertions(+), 70 deletions(-) diff --git a/sound/firewire/fireface/ff-pcm.c b/sound/firewire/fireface/ff-pcm.c index d0bc96b20a65..5adf04b95c04 100644 --- a/sound/firewire/fireface/ff-pcm.c +++ b/sound/firewire/fireface/ff-pcm.c @@ -152,7 +152,7 @@ static int pcm_open(struct snd_pcm_substream *substream) if (err < 0) goto release_lock; - err = snd_ff_transaction_get_clock(ff, &rate, &src); + err = ff->spec->protocol->get_clock(ff, &rate, &src); if (err < 0) goto release_lock; diff --git a/sound/firewire/fireface/ff-protocol-former.c b/sound/firewire/fireface/ff-protocol-former.c index 279bd032acf0..d32104ed0c08 100644 --- a/sound/firewire/fireface/ff-protocol-former.c +++ b/sound/firewire/fireface/ff-protocol-former.c @@ -12,6 +12,70 @@ #define FORMER_REG_SYNC_STATUS 0x0000801c0000ull /* For block write request. */ #define FORMER_REG_FETCH_PCM_FRAMES 0x0000801c0000ull +#define FORMER_REG_CLOCK_CONFIG 0x0000801c0004ull + +static int former_get_clock(struct snd_ff *ff, unsigned int *rate, + enum snd_ff_clock_src *src) +{ + __le32 reg; + u32 data; + int err; + + err = snd_fw_transaction(ff->unit, TCODE_READ_QUADLET_REQUEST, + FORMER_REG_CLOCK_CONFIG, ®, sizeof(reg), 0); + if (err < 0) + return err; + data = le32_to_cpu(reg); + + /* Calculate sampling rate. */ + switch ((data >> 1) & 0x03) { + case 0x01: + *rate = 32000; + break; + case 0x00: + *rate = 44100; + break; + case 0x03: + *rate = 48000; + break; + case 0x02: + default: + return -EIO; + } + + if (data & 0x08) + *rate *= 2; + else if (data & 0x10) + *rate *= 4; + + /* Calculate source of clock. */ + if (data & 0x01) { + *src = SND_FF_CLOCK_SRC_INTERNAL; + } else { + /* TODO: 0x02, 0x06, 0x07? */ + switch ((data >> 10) & 0x07) { + case 0x00: + *src = SND_FF_CLOCK_SRC_ADAT1; + break; + case 0x01: + *src = SND_FF_CLOCK_SRC_ADAT2; + break; + case 0x03: + *src = SND_FF_CLOCK_SRC_SPDIF; + break; + case 0x04: + *src = SND_FF_CLOCK_SRC_WORD; + break; + case 0x05: + *src = SND_FF_CLOCK_SRC_LTC; + break; + default: + return -EIO; + } + } + + return 0; +} static int former_switch_fetching_mode(struct snd_ff *ff, bool enable) { @@ -56,7 +120,7 @@ static void dump_clock_config(struct snd_ff *ff, struct snd_info_buffer *buffer) int err; err = snd_fw_transaction(ff->unit, TCODE_READ_BLOCK_REQUEST, - SND_FF_REG_CLOCK_CONFIG, ®, sizeof(reg), 0); + FORMER_REG_CLOCK_CONFIG, ®, sizeof(reg), 0); if (err < 0) return; @@ -383,6 +447,7 @@ static void ff800_handle_midi_msg(struct snd_ff *ff, __le32 *buf, size_t length) const struct snd_ff_protocol snd_ff_protocol_ff800 = { .handle_midi_msg = ff800_handle_midi_msg, + .get_clock = former_get_clock, .switch_fetching_mode = former_switch_fetching_mode, .begin_session = ff800_begin_session, .finish_session = ff800_finish_session, @@ -532,6 +597,7 @@ static void ff400_handle_midi_msg(struct snd_ff *ff, __le32 *buf, size_t length) const struct snd_ff_protocol snd_ff_protocol_ff400 = { .handle_midi_msg = ff400_handle_midi_msg, + .get_clock = former_get_clock, .switch_fetching_mode = former_switch_fetching_mode, .begin_session = ff400_begin_session, .finish_session = ff400_finish_session, diff --git a/sound/firewire/fireface/ff-stream.c b/sound/firewire/fireface/ff-stream.c index 43e1e2679798..a8a90f1ae09e 100644 --- a/sound/firewire/fireface/ff-stream.c +++ b/sound/firewire/fireface/ff-stream.c @@ -113,7 +113,7 @@ int snd_ff_stream_start_duplex(struct snd_ff *ff, unsigned int rate) if (ff->substreams_counter == 0) return 0; - err = snd_ff_transaction_get_clock(ff, &curr_rate, &src); + err = ff->spec->protocol->get_clock(ff, &curr_rate, &src); if (err < 0) return err; if (curr_rate != rate || diff --git a/sound/firewire/fireface/ff-transaction.c b/sound/firewire/fireface/ff-transaction.c index 5f4ddfd55403..065e045d3fb5 100644 --- a/sound/firewire/fireface/ff-transaction.c +++ b/sound/firewire/fireface/ff-transaction.c @@ -11,69 +11,6 @@ #define SND_FF_REG_MIDI_RX_PORT_0 0x000080180000ull #define SND_FF_REG_MIDI_RX_PORT_1 0x000080190000ull -int snd_ff_transaction_get_clock(struct snd_ff *ff, unsigned int *rate, - enum snd_ff_clock_src *src) -{ - __le32 reg; - u32 data; - int err; - - err = snd_fw_transaction(ff->unit, TCODE_READ_QUADLET_REQUEST, - SND_FF_REG_CLOCK_CONFIG, ®, sizeof(reg), 0); - if (err < 0) - return err; - data = le32_to_cpu(reg); - - /* Calculate sampling rate. */ - switch ((data >> 1) & 0x03) { - case 0x01: - *rate = 32000; - break; - case 0x00: - *rate = 44100; - break; - case 0x03: - *rate = 48000; - break; - case 0x02: - default: - return -EIO; - } - - if (data & 0x08) - *rate *= 2; - else if (data & 0x10) - *rate *= 4; - - /* Calculate source of clock. */ - if (data & 0x01) { - *src = SND_FF_CLOCK_SRC_INTERNAL; - } else { - /* TODO: 0x02, 0x06, 0x07? */ - switch ((data >> 10) & 0x07) { - case 0x00: - *src = SND_FF_CLOCK_SRC_ADAT1; - break; - case 0x01: - *src = SND_FF_CLOCK_SRC_ADAT2; - break; - case 0x03: - *src = SND_FF_CLOCK_SRC_SPDIF; - break; - case 0x04: - *src = SND_FF_CLOCK_SRC_WORD; - break; - case 0x05: - *src = SND_FF_CLOCK_SRC_LTC; - break; - default: - return -EIO; - } - } - - return 0; -} - static void finish_transmit_midi_msg(struct snd_ff *ff, unsigned int port, int rcode) { diff --git a/sound/firewire/fireface/ff.h b/sound/firewire/fireface/ff.h index 29f55518bf85..1de2f5ec26fd 100644 --- a/sound/firewire/fireface/ff.h +++ b/sound/firewire/fireface/ff.h @@ -35,8 +35,6 @@ #define SND_FF_IN_MIDI_PORTS 2 #define SND_FF_OUT_MIDI_PORTS 2 -#define SND_FF_REG_CLOCK_CONFIG 0x0000801c0004ull - enum snd_ff_stream_mode { SND_FF_STREAM_MODE_LOW = 0, SND_FF_STREAM_MODE_MID, @@ -106,6 +104,8 @@ enum snd_ff_clock_src { struct snd_ff_protocol { void (*handle_midi_msg)(struct snd_ff *ff, __le32 *buf, size_t length); + int (*get_clock)(struct snd_ff *ff, unsigned int *rate, + enum snd_ff_clock_src *src); int (*switch_fetching_mode)(struct snd_ff *ff, bool enable); int (*begin_session)(struct snd_ff *ff, unsigned int rate); void (*finish_session)(struct snd_ff *ff); @@ -115,8 +115,6 @@ struct snd_ff_protocol { extern const struct snd_ff_protocol snd_ff_protocol_ff800; extern const struct snd_ff_protocol snd_ff_protocol_ff400; -int snd_ff_transaction_get_clock(struct snd_ff *ff, unsigned int *rate, - enum snd_ff_clock_src *src); int snd_ff_transaction_register(struct snd_ff *ff); int snd_ff_transaction_reregister(struct snd_ff *ff); void snd_ff_transaction_unregister(struct snd_ff *ff); From patchwork Sun Jan 20 08:25:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takashi Sakamoto X-Patchwork-Id: 10772333 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E74156C2 for ; Sun, 20 Jan 2019 08:27:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DAC402ADF3 for ; Sun, 20 Jan 2019 08:27:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CEDB82ADF5; Sun, 20 Jan 2019 08:27:14 +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=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, 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 0C2EA2ADF3 for ; Sun, 20 Jan 2019 08:27:14 +0000 (UTC) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id AD0052673F9; Sun, 20 Jan 2019 09:26:31 +0100 (CET) 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 6BC97267428; Sun, 20 Jan 2019 09:26:24 +0100 (CET) Received: from mail-pl1-f172.google.com (mail-pl1-f172.google.com [209.85.214.172]) by alsa0.perex.cz (Postfix) with ESMTP id 35FB9267350 for ; Sun, 20 Jan 2019 09:26:21 +0100 (CET) Received: by mail-pl1-f172.google.com with SMTP id e11so8293111plt.11 for ; Sun, 20 Jan 2019 00:26:21 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=yll3Uk1NP533e9sQ8ueohDgjFfWaZZrC/FjMCDR8/Ck=; b=ppnZ3G8Ax0mEPCtaCLJ8K/wdtd1YBBxoJpmzFZHhXt5ORxYbkVreRvI1RV35TXn4YN wp72wJueWyn8nHEbRsNqm/tiW9qS+gPles+5Vhx1fpNKjKi3zAsK259S8CpJIFcQdbvo tsdCx0FGGQAl7HVw8QPi2S8qaPVs3k7X53C018a0LV3+XWFe5X8FqVumdTNSO5DSc17U EkZgOD1W3bSzOaIlBHfHaO7FQyOYaaZAKXvJocHEa6jbKaLwLuGsggluHXDKQeigsd8g pZ8FfDkuTJ/GC9JsCamCbDWWc0riy3+ix3MvOWTbAtyv64ku3ROJvKxLC874BbUxsDOz ichw== X-Gm-Message-State: AJcUukeUAUOJCNWwJZ5LC4eSXTNnhbOyoF3LLHK0fWdWdRCQxpVcLTlN Z32uV2IuvA7vxhpvFQYLOec= X-Google-Smtp-Source: ALg8bN6xbhXxaqecwj6Yce+8gaXCW97oasq8CZxslZKWoJDb2Dvls9j43DUuD3UCgrkpvOzBci9BIg== X-Received: by 2002:a17:902:8346:: with SMTP id z6mr25513653pln.340.1547972781026; Sun, 20 Jan 2019 00:26:21 -0800 (PST) Received: from localhost.localdomain ([2405:6580:9660:3200:489b:ac9:70e4:1515]) by smtp.gmail.com with ESMTPSA id z186sm12214046pfz.119.2019.01.20.00.26.19 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 20 Jan 2019 00:26:20 -0800 (PST) From: Takashi Sakamoto To: clemens@ladisch.de, tiwai@suse.de Date: Sun, 20 Jan 2019 17:25:51 +0900 Message-Id: <20190120082553.17347-8-o-takashi@sakamocchi.jp> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190120082553.17347-1-o-takashi@sakamocchi.jp> References: <20190120082553.17347-1-o-takashi@sakamocchi.jp> MIME-Version: 1.0 Cc: alsa-devel@alsa-project.org, ffado-devel@lists.sourceforge.net Subject: [alsa-devel] [PATCH 7/9] ALSA: fireface: code refactoring for dump of sync status 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 This commit adds refactoring for dump of sync status by adding tables for check bits. Signed-off-by: Takashi Sakamoto --- sound/firewire/fireface/ff-protocol-former.c | 176 ++++++++----------- 1 file changed, 75 insertions(+), 101 deletions(-) diff --git a/sound/firewire/fireface/ff-protocol-former.c b/sound/firewire/fireface/ff-protocol-former.c index d32104ed0c08..fb2af10d2690 100644 --- a/sound/firewire/fireface/ff-protocol-former.c +++ b/sound/firewire/fireface/ff-protocol-former.c @@ -190,126 +190,100 @@ static void dump_clock_config(struct snd_ff *ff, struct snd_info_buffer *buffer) static void dump_sync_status(struct snd_ff *ff, struct snd_info_buffer *buffer) { - __le32 reg; - u32 data; + static const struct { + char *const label; + u32 locked_mask; + u32 synced_mask; + } *clk_entry, clk_entries[] = { + { "WDClk", 0x40000000, 0x20000000, }, + { "S/PDIF", 0x00080000, 0x00040000, }, + { "ADAT1", 0x00000400, 0x00001000, }, + { "ADAT2", 0x00000800, 0x00002000, }, + }; + static const struct { + char *const label; + u32 mask; + } *referred_entry, referred_entries[] = { + { "ADAT1", 0x00000000, }, + { "ADAT2", 0x00400000, }, + { "S/PDIF", 0x00c00000, }, + { "WDclk", 0x01000000, }, + { "TCO", 0x01400000, }, + }; + static const struct { + unsigned int rate; + u32 mask; + } *rate_entry, rate_entries[] = { + { 32000, 0x02000000, }, + { 44100, 0x04000000, }, + { 48000, 0x06000000, }, + { 64000, 0x08000000, }, + { 88200, 0x0a000000, }, + { 96000, 0x0c000000, }, + { 128000, 0x0e000000, }, + { 176400, 0x10000000, }, + { 192000, 0x12000000, }, + }; + __le32 reg[2]; + u32 data[2]; + int i; int err; - err = snd_fw_transaction(ff->unit, TCODE_READ_QUADLET_REQUEST, - FORMER_REG_SYNC_STATUS, ®, sizeof(reg), 0); + err = snd_fw_transaction(ff->unit, TCODE_READ_BLOCK_REQUEST, + FORMER_REG_SYNC_STATUS, reg, sizeof(reg), 0); if (err < 0) return; - - data = le32_to_cpu(reg); + data[0] = le32_to_cpu(reg[0]); + data[1] = le32_to_cpu(reg[1]); snd_iprintf(buffer, "External source detection:\n"); - snd_iprintf(buffer, "Word Clock:"); - if ((data >> 24) & 0x20) { - if ((data >> 24) & 0x40) - snd_iprintf(buffer, "sync\n"); - else - snd_iprintf(buffer, "lock\n"); - } else { - snd_iprintf(buffer, "none\n"); - } + for (i = 0; i < ARRAY_SIZE(clk_entries); ++i) { + const char *state; + + clk_entry = clk_entries + i; + if (data[0] & clk_entry->locked_mask) { + if (data[0] & clk_entry->synced_mask) + state = "sync"; + else + state = "lock"; + } else { + state = "none"; + } - snd_iprintf(buffer, "S/PDIF:"); - if ((data >> 16) & 0x10) { - if ((data >> 16) & 0x04) - snd_iprintf(buffer, "sync\n"); - else - snd_iprintf(buffer, "lock\n"); - } else { - snd_iprintf(buffer, "none\n"); + snd_iprintf(buffer, "%s: %s\n", clk_entry->label, state); } - snd_iprintf(buffer, "ADAT1:"); - if ((data >> 8) & 0x04) { - if ((data >> 8) & 0x10) - snd_iprintf(buffer, "sync\n"); - else - snd_iprintf(buffer, "lock\n"); - } else { - snd_iprintf(buffer, "none\n"); - } + snd_iprintf(buffer, "Referred clock:\n"); - snd_iprintf(buffer, "ADAT2:"); - if ((data >> 8) & 0x08) { - if ((data >> 8) & 0x20) - snd_iprintf(buffer, "sync\n"); - else - snd_iprintf(buffer, "lock\n"); + if (data[1] & 0x00000001) { + snd_iprintf(buffer, "Internal\n"); } else { - snd_iprintf(buffer, "none\n"); - } + unsigned int rate; + const char *label; - snd_iprintf(buffer, "\nUsed external source:\n"); - - if (((data >> 22) & 0x07) == 0x07) { - snd_iprintf(buffer, "None\n"); - } else { - switch ((data >> 22) & 0x07) { - case 0x00: - snd_iprintf(buffer, "ADAT1:"); - break; - case 0x01: - snd_iprintf(buffer, "ADAT2:"); - break; - case 0x03: - snd_iprintf(buffer, "S/PDIF:"); - break; - case 0x04: - snd_iprintf(buffer, "Word:"); - break; - case 0x07: - snd_iprintf(buffer, "Nothing:"); - break; - case 0x02: - case 0x05: - case 0x06: - default: - snd_iprintf(buffer, "unknown:"); - break; + for (i = 0; i < ARRAY_SIZE(referred_entries); ++i) { + referred_entry = referred_entries + i; + if ((data[0] & 0x1e0000) == referred_entry->mask) { + label = referred_entry->label; + break; + } } + if (i == ARRAY_SIZE(referred_entries)) + label = "none"; - if ((data >> 25) & 0x07) { - switch ((data >> 25) & 0x07) { - case 0x01: - snd_iprintf(buffer, "32000\n"); - break; - case 0x02: - snd_iprintf(buffer, "44100\n"); - break; - case 0x03: - snd_iprintf(buffer, "48000\n"); - break; - case 0x04: - snd_iprintf(buffer, "64000\n"); - break; - case 0x05: - snd_iprintf(buffer, "88200\n"); - break; - case 0x06: - snd_iprintf(buffer, "96000\n"); - break; - case 0x07: - snd_iprintf(buffer, "128000\n"); - break; - case 0x08: - snd_iprintf(buffer, "176400\n"); - break; - case 0x09: - snd_iprintf(buffer, "192000\n"); - break; - case 0x00: - snd_iprintf(buffer, "unknown\n"); + for (i = 0; i < ARRAY_SIZE(rate_entries); ++i) { + rate_entry = rate_entries + i; + if ((data[0] & 0x1e000000) == rate_entry->mask) { + rate = rate_entry->rate; break; } } - } + if (i == ARRAY_SIZE(rate_entries)) + rate = 0; - snd_iprintf(buffer, "Multiplied:"); - snd_iprintf(buffer, "%d\n", (data & 0x3ff) * 250); + snd_iprintf(buffer, "%s %d\n", label, rate); + } } static void former_dump_status(struct snd_ff *ff, From patchwork Sun Jan 20 08:25:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takashi Sakamoto X-Patchwork-Id: 10772335 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 35715746 for ; Sun, 20 Jan 2019 08:27:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 28C3D2ADF3 for ; Sun, 20 Jan 2019 08:27:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1CCC52ADF4; Sun, 20 Jan 2019 08:27:23 +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=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, 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 3BA732ADF7 for ; Sun, 20 Jan 2019 08:27:22 +0000 (UTC) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 2812126745A; Sun, 20 Jan 2019 09:26:33 +0100 (CET) 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 ECA8A267439; Sun, 20 Jan 2019 09:26:25 +0100 (CET) Received: from mail-pf1-f193.google.com (mail-pf1-f193.google.com [209.85.210.193]) by alsa0.perex.cz (Postfix) with ESMTP id 1E24826742B for ; Sun, 20 Jan 2019 09:26:23 +0100 (CET) Received: by mail-pf1-f193.google.com with SMTP id y126so8702400pfb.4 for ; Sun, 20 Jan 2019 00:26:23 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=0Y6s4335/Tbr4iGOQiSQLTL72WgbA3KxZTes01o/k+A=; b=DTUGb82PR+zyJZhaR0D0iVThxDUafjkl7/VudA/huqCxVmu9CMwoip7SWy5fYcvdut 4yxOEAx6DYm/Mpx8GdaTksiBybKHdanfQ84Ixucs6Z+Xjrl4+DxR50DHqr8uvBUYzY1I fkFNsqH6srlFVzpRHrMxFNIZD/Njzvt//TQLj87cwxzuNw3VLGR5CQipwSn3F6Qr8EJ9 5HKSkYE/wC/h+eKrqu+UOxSH+Y5eG8qsg5Ea/npO4GRjZ1xULUZA+m6WtmvM8Rzny+Lt BqF0Qzq618djpaI/KVfyumK/TADt0CY0t9WrIs8Zn8bPsSHbNm2j1+QNvXaZpf4AbnC6 jEew== X-Gm-Message-State: AJcUukdanINQEyeXGrq0AFyJxynSK9b6V9q9i4JtsXqwcQ9jIrfc/DHn oxtCAPFQrAuRyn8T74WsON8= X-Google-Smtp-Source: ALg8bN7r99XQ2d95PdlJSRH1EBUE22nOdzmslG8Y3vLkPHnirFFOXa/F7Uwz50jQnbQkkbotM4tL+Q== X-Received: by 2002:a63:4926:: with SMTP id w38mr22970919pga.353.1547972782871; Sun, 20 Jan 2019 00:26:22 -0800 (PST) Received: from localhost.localdomain ([2405:6580:9660:3200:489b:ac9:70e4:1515]) by smtp.gmail.com with ESMTPSA id z186sm12214046pfz.119.2019.01.20.00.26.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 20 Jan 2019 00:26:22 -0800 (PST) From: Takashi Sakamoto To: clemens@ladisch.de, tiwai@suse.de Date: Sun, 20 Jan 2019 17:25:52 +0900 Message-Id: <20190120082553.17347-9-o-takashi@sakamocchi.jp> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190120082553.17347-1-o-takashi@sakamocchi.jp> References: <20190120082553.17347-1-o-takashi@sakamocchi.jp> MIME-Version: 1.0 Cc: alsa-devel@alsa-project.org, ffado-devel@lists.sourceforge.net Subject: [alsa-devel] [PATCH 8/9] ALSA: fireface: code refactoring to parse of clock configuration 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 A procedure to retrieve clock configuration is used by two callers. Each of caller has duplicated code to parse bits. This commit adds refactoring to remove the duplicated code. Signed-off-by: Takashi Sakamoto --- sound/firewire/fireface/ff-proc.c | 17 ++ sound/firewire/fireface/ff-protocol-former.c | 172 ++++++++----------- sound/firewire/fireface/ff.h | 1 + 3 files changed, 89 insertions(+), 101 deletions(-) diff --git a/sound/firewire/fireface/ff-proc.c b/sound/firewire/fireface/ff-proc.c index 8a7cfb6ccce6..a55e68ec1832 100644 --- a/sound/firewire/fireface/ff-proc.c +++ b/sound/firewire/fireface/ff-proc.c @@ -8,6 +8,23 @@ #include "./ff.h" +const char *snd_ff_proc_get_clk_label(enum snd_ff_clock_src src) +{ + static const char *const labels[] = { + "Internal", + "S/PDIF", + "ADAT1", + "ADAT2", + "Word", + "LTC", + }; + + if (src >= ARRAY_SIZE(labels)) + return NULL; + + return labels[src]; +} + static void proc_dump_status(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { diff --git a/sound/firewire/fireface/ff-protocol-former.c b/sound/firewire/fireface/ff-protocol-former.c index fb2af10d2690..9c0ae50e88d1 100644 --- a/sound/firewire/fireface/ff-protocol-former.c +++ b/sound/firewire/fireface/ff-protocol-former.c @@ -14,6 +14,62 @@ #define FORMER_REG_FETCH_PCM_FRAMES 0x0000801c0000ull #define FORMER_REG_CLOCK_CONFIG 0x0000801c0004ull +static int parse_clock_bits(u32 data, unsigned int *rate, + enum snd_ff_clock_src *src) +{ + static const struct { + unsigned int rate; + u32 mask; + } *rate_entry, rate_entries[] = { + { 32000, 0x00000002, }, + { 44100, 0x00000000, }, + { 48000, 0x00000006, }, + { 64000, 0x0000000a, }, + { 88200, 0x00000008, }, + { 96000, 0x0000000e, }, + { 128000, 0x00000012, }, + { 176400, 0x00000010, }, + { 192000, 0x00000016, }, + }; + static const struct { + enum snd_ff_clock_src src; + u32 mask; + } *clk_entry, clk_entries[] = { + { SND_FF_CLOCK_SRC_ADAT1, 0x00000000, }, + { SND_FF_CLOCK_SRC_ADAT2, 0x00000400, }, + { SND_FF_CLOCK_SRC_SPDIF, 0x00000c00, }, + { SND_FF_CLOCK_SRC_WORD, 0x00001000, }, + { SND_FF_CLOCK_SRC_LTC, 0x00001800, }, + }; + int i; + + for (i = 0; i < ARRAY_SIZE(rate_entries); ++i) { + rate_entry = rate_entries + i; + if ((data & 0x0000001e) == rate_entry->mask) { + *rate = rate_entry->rate; + break; + } + } + if (i == ARRAY_SIZE(rate_entries)) + return -EIO; + + if (data & 0x00000001) { + *src = SND_FF_CLOCK_SRC_INTERNAL; + } else { + for (i = 0; i < ARRAY_SIZE(clk_entries); ++i) { + clk_entry = clk_entries + i; + if ((data & 0x00001c00) == clk_entry->mask) { + *src = clk_entry->src; + break; + } + } + if (i == ARRAY_SIZE(clk_entries)) + return -EIO; + } + + return 0; +} + static int former_get_clock(struct snd_ff *ff, unsigned int *rate, enum snd_ff_clock_src *src) { @@ -27,54 +83,7 @@ static int former_get_clock(struct snd_ff *ff, unsigned int *rate, return err; data = le32_to_cpu(reg); - /* Calculate sampling rate. */ - switch ((data >> 1) & 0x03) { - case 0x01: - *rate = 32000; - break; - case 0x00: - *rate = 44100; - break; - case 0x03: - *rate = 48000; - break; - case 0x02: - default: - return -EIO; - } - - if (data & 0x08) - *rate *= 2; - else if (data & 0x10) - *rate *= 4; - - /* Calculate source of clock. */ - if (data & 0x01) { - *src = SND_FF_CLOCK_SRC_INTERNAL; - } else { - /* TODO: 0x02, 0x06, 0x07? */ - switch ((data >> 10) & 0x07) { - case 0x00: - *src = SND_FF_CLOCK_SRC_ADAT1; - break; - case 0x01: - *src = SND_FF_CLOCK_SRC_ADAT2; - break; - case 0x03: - *src = SND_FF_CLOCK_SRC_SPDIF; - break; - case 0x04: - *src = SND_FF_CLOCK_SRC_WORD; - break; - case 0x05: - *src = SND_FF_CLOCK_SRC_LTC; - break; - default: - return -EIO; - } - } - - return 0; + return parse_clock_bits(data, rate, src); } static int former_switch_fetching_mode(struct snd_ff *ff, bool enable) @@ -116,76 +125,37 @@ static void dump_clock_config(struct snd_ff *ff, struct snd_info_buffer *buffer) __le32 reg; u32 data; unsigned int rate; - const char *src; + enum snd_ff_clock_src src; + const char *label; int err; err = snd_fw_transaction(ff->unit, TCODE_READ_BLOCK_REQUEST, FORMER_REG_CLOCK_CONFIG, ®, sizeof(reg), 0); if (err < 0) return; - data = le32_to_cpu(reg); snd_iprintf(buffer, "Output S/PDIF format: %s (Emphasis: %s)\n", - (data & 0x20) ? "Professional" : "Consumer", - (data & 0x40) ? "on" : "off"); + (data & 0x00000020) ? "Professional" : "Consumer", + (data & 0x00000040) ? "on" : "off"); snd_iprintf(buffer, "Optical output interface format: %s\n", - ((data >> 8) & 0x01) ? "S/PDIF" : "ADAT"); + (data & 0x00000100) ? "S/PDIF" : "ADAT"); snd_iprintf(buffer, "Word output single speed: %s\n", - ((data >> 8) & 0x20) ? "on" : "off"); + (data & 0x00002000) ? "on" : "off"); snd_iprintf(buffer, "S/PDIF input interface: %s\n", - ((data >> 8) & 0x02) ? "Optical" : "Coaxial"); - - switch ((data >> 1) & 0x03) { - case 0x01: - rate = 32000; - break; - case 0x00: - rate = 44100; - break; - case 0x03: - rate = 48000; - break; - case 0x02: - default: - return; - } - - if (data & 0x08) - rate *= 2; - else if (data & 0x10) - rate *= 4; - - snd_iprintf(buffer, "Sampling rate: %d\n", rate); + (data & 0x00000200) ? "Optical" : "Coaxial"); - if (data & 0x01) { - src = "Internal"; - } else { - switch ((data >> 10) & 0x07) { - case 0x00: - src = "ADAT1"; - break; - case 0x01: - src = "ADAT2"; - break; - case 0x03: - src = "S/PDIF"; - break; - case 0x04: - src = "Word"; - break; - case 0x05: - src = "LTC"; - break; - default: - return; - } - } + err = parse_clock_bits(data, &rate, &src); + if (err < 0) + return; + label = snd_ff_proc_get_clk_label(src); + if (!label) + return; - snd_iprintf(buffer, "Sync to clock source: %s\n", src); + snd_iprintf(buffer, "Clock configuration: %d %s\n", rate, label); } static void dump_sync_status(struct snd_ff *ff, struct snd_info_buffer *buffer) diff --git a/sound/firewire/fireface/ff.h b/sound/firewire/fireface/ff.h index 1de2f5ec26fd..cdb16e931c31 100644 --- a/sound/firewire/fireface/ff.h +++ b/sound/firewire/fireface/ff.h @@ -139,6 +139,7 @@ int snd_ff_stream_lock_try(struct snd_ff *ff); void snd_ff_stream_lock_release(struct snd_ff *ff); void snd_ff_proc_init(struct snd_ff *ff); +const char *snd_ff_proc_get_clk_label(enum snd_ff_clock_src src); int snd_ff_create_midi_devices(struct snd_ff *ff); From patchwork Sun Jan 20 08:25:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takashi Sakamoto X-Patchwork-Id: 10772337 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E4A296C2 for ; Sun, 20 Jan 2019 08:27:32 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D56912ADF3 for ; Sun, 20 Jan 2019 08:27:32 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C9AF62ADF5; Sun, 20 Jan 2019 08:27:32 +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=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, 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 8789D2ADF3 for ; Sun, 20 Jan 2019 08:27:31 +0000 (UTC) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 0FB57267468; Sun, 20 Jan 2019 09:26:37 +0100 (CET) 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 7A6AC2673F9; Sun, 20 Jan 2019 09:26:31 +0100 (CET) Received: from mail-pg1-f196.google.com (mail-pg1-f196.google.com [209.85.215.196]) by alsa0.perex.cz (Postfix) with ESMTP id 03A00267350 for ; Sun, 20 Jan 2019 09:26:25 +0100 (CET) Received: by mail-pg1-f196.google.com with SMTP id t13so8061355pgr.11 for ; Sun, 20 Jan 2019 00:26:25 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=jCWMXXk7wLu+m8F5GUVetdBPOpaCCVHvTIQijdvQc50=; b=KbYdoCSGENQx4jvBnQXhWSv9/tatCttvx14aUK8N6p0tCVcIPfMvbeQP9MbpYCGxyA 0tiGAcNwv56gKJqQU+mn6QfEWu+TIv6enBcMZktdVbdITt35A6TSOoS6qFONeIkgI7Sm zZRdtX2fbSSKIB4wepMcGTgnESYy6LT2kSBD2vCzKA2XYEFWuiMGHwCKNXSmsHnXB3Gh JfjOqu+2ZsDh6Ae7dNjEJDaFVFqJZqDpXJX83R3h2dNZFPoeuPVRSHIFWgh0gma2EVoo ikz+WHD1IxwBmH2QNz4Oyj3kl+fhTdM4LE0V8HsNycnjTGymsg5EgI6nH71wanf7NuPs o61A== X-Gm-Message-State: AJcUukfjnfX1KzBkQHHRTUuGvskp7o5Yd0dQFrX6u1pDCSUy2zzMFe8m AjeUT603uBtLSG5WQqyrEMr/JlTc X-Google-Smtp-Source: ALg8bN6ZqM3U5EyzcQYupKAdT1+rm/ixKYIeeR1zEYsiyxMQ8r2zK62miqbL8qpW6p/KUPyWHacLlQ== X-Received: by 2002:a65:448a:: with SMTP id l10mr23918753pgq.387.1547972784730; Sun, 20 Jan 2019 00:26:24 -0800 (PST) Received: from localhost.localdomain ([2405:6580:9660:3200:489b:ac9:70e4:1515]) by smtp.gmail.com with ESMTPSA id z186sm12214046pfz.119.2019.01.20.00.26.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 20 Jan 2019 00:26:24 -0800 (PST) From: Takashi Sakamoto To: clemens@ladisch.de, tiwai@suse.de Date: Sun, 20 Jan 2019 17:25:53 +0900 Message-Id: <20190120082553.17347-10-o-takashi@sakamocchi.jp> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190120082553.17347-1-o-takashi@sakamocchi.jp> References: <20190120082553.17347-1-o-takashi@sakamocchi.jp> MIME-Version: 1.0 Cc: alsa-devel@alsa-project.org, ffado-devel@lists.sourceforge.net Subject: [alsa-devel] [PATCH 9/9] ALSA: fireface: add support for Fireface UCX 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 Fireface UFX was shipped by RME GmbH in 2012. This model supports later protocol for management of isochronous communication and synchronization of sampling transmission frequency. This commit adds support for the model. At present, it's not clear how to encode MIDI messages and decide destination address for asynchronous transaction, thus this commit adds support for isochronous communication for PCM frames only. Signed-off-by: Takashi Sakamoto --- sound/firewire/Kconfig | 1 + sound/firewire/fireface/Makefile | 3 +- sound/firewire/fireface/ff-protocol-latter.c | 273 +++++++++++++++++++ sound/firewire/fireface/ff.c | 41 ++- sound/firewire/fireface/ff.h | 1 + 5 files changed, 310 insertions(+), 9 deletions(-) create mode 100644 sound/firewire/fireface/ff-protocol-latter.c diff --git a/sound/firewire/Kconfig b/sound/firewire/Kconfig index 052e00590259..b9e96d0b3a0a 100644 --- a/sound/firewire/Kconfig +++ b/sound/firewire/Kconfig @@ -163,5 +163,6 @@ config SND_FIREFACE Say Y here to include support for RME fireface series. * Fireface 400 * Fireface 800 + * Fireface UCX endif # SND_FIREWIRE diff --git a/sound/firewire/fireface/Makefile b/sound/firewire/fireface/Makefile index 62eb78962b93..d64f4e2a1096 100644 --- a/sound/firewire/fireface/Makefile +++ b/sound/firewire/fireface/Makefile @@ -1,3 +1,4 @@ snd-fireface-objs := ff.o ff-transaction.o ff-midi.o ff-proc.o amdtp-ff.o \ - ff-stream.o ff-pcm.o ff-hwdep.o ff-protocol-former.o + ff-stream.o ff-pcm.o ff-hwdep.o ff-protocol-former.o \ + ff-protocol-latter.o obj-$(CONFIG_SND_FIREFACE) += snd-fireface.o diff --git a/sound/firewire/fireface/ff-protocol-latter.c b/sound/firewire/fireface/ff-protocol-latter.c new file mode 100644 index 000000000000..64767ba439db --- /dev/null +++ b/sound/firewire/fireface/ff-protocol-latter.c @@ -0,0 +1,273 @@ +// SPDX-License-Identifier: GPL-2.0 +// ff-protocol-latter - a part of driver for RME Fireface series +// +// Copyright (c) 2019 Takashi Sakamoto +// +// Licensed under the terms of the GNU General Public License, version 2. + +#include + +#include "ff.h" + +#define LATTER_STF 0xffff00000004 +#define LATTER_ISOC_CHANNELS 0xffff00000008 +#define LATTER_ISOC_START 0xffff0000000c +#define LATTER_FETCH_MODE 0xffff00000010 +#define LATTER_SYNC_STATUS 0x0000801c0000 + +static int parse_clock_bits(u32 data, unsigned int *rate, + enum snd_ff_clock_src *src) +{ + static const struct { + unsigned int rate; + u32 flag; + } *rate_entry, rate_entries[] = { + { 32000, 0x00000000, }, + { 44100, 0x01000000, }, + { 48000, 0x02000000, }, + { 64000, 0x04000000, }, + { 88200, 0x05000000, }, + { 96000, 0x06000000, }, + { 128000, 0x08000000, }, + { 176400, 0x09000000, }, + { 192000, 0x0a000000, }, + }; + static const struct { + enum snd_ff_clock_src src; + u32 flag; + } *clk_entry, clk_entries[] = { + { SND_FF_CLOCK_SRC_SPDIF, 0x00000200, }, + { SND_FF_CLOCK_SRC_ADAT1, 0x00000400, }, + { SND_FF_CLOCK_SRC_WORD, 0x00000600, }, + { SND_FF_CLOCK_SRC_INTERNAL, 0x00000e00, }, + }; + int i; + + for (i = 0; i < ARRAY_SIZE(rate_entries); ++i) { + rate_entry = rate_entries + i; + if ((data & 0x0f000000) == rate_entry->flag) { + *rate = rate_entry->rate; + break; + } + } + if (i == ARRAY_SIZE(rate_entries)) + return -EIO; + + for (i = 0; i < ARRAY_SIZE(clk_entries); ++i) { + clk_entry = clk_entries + i; + if ((data & 0x000e00) == clk_entry->flag) { + *src = clk_entry->src; + break; + } + } + if (i == ARRAY_SIZE(clk_entries)) + return -EIO; + + return 0; +} + +static int latter_get_clock(struct snd_ff *ff, unsigned int *rate, + enum snd_ff_clock_src *src) +{ + __le32 reg; + u32 data; + int err; + + err = snd_fw_transaction(ff->unit, TCODE_READ_QUADLET_REQUEST, + LATTER_SYNC_STATUS, ®, sizeof(reg), 0); + if (err < 0) + return err; + data = le32_to_cpu(reg); + + return parse_clock_bits(data, rate, src); +} + +static int latter_switch_fetching_mode(struct snd_ff *ff, bool enable) +{ + u32 data; + __le32 reg; + + if (enable) + data = 0x00000000; + else + data = 0xffffffff; + reg = cpu_to_le32(data); + + return snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST, + LATTER_FETCH_MODE, ®, sizeof(reg), 0); +} + +static int keep_resources(struct snd_ff *ff, unsigned int rate) +{ + enum snd_ff_stream_mode mode; + int i; + int err; + + // Check whether the given value is supported or not. + for (i = 0; i < CIP_SFC_COUNT; i++) { + if (amdtp_rate_table[i] == rate) + break; + } + if (i >= CIP_SFC_COUNT) + return -EINVAL; + + err = snd_ff_stream_get_multiplier_mode(i, &mode); + if (err < 0) + return err; + + /* Keep resources for in-stream. */ + ff->tx_resources.channels_mask = 0x00000000000000ffuLL; + err = fw_iso_resources_allocate(&ff->tx_resources, + amdtp_stream_get_max_payload(&ff->tx_stream), + fw_parent_device(ff->unit)->max_speed); + if (err < 0) + return err; + + /* Keep resources for out-stream. */ + ff->rx_resources.channels_mask = 0x00000000000000ffuLL; + err = fw_iso_resources_allocate(&ff->rx_resources, + amdtp_stream_get_max_payload(&ff->rx_stream), + fw_parent_device(ff->unit)->max_speed); + if (err < 0) + fw_iso_resources_free(&ff->tx_resources); + + return err; +} + +static int latter_begin_session(struct snd_ff *ff, unsigned int rate) +{ + static const struct { + unsigned int stf; + unsigned int code; + unsigned int flag; + } *entry, rate_table[] = { + { 32000, 0x00, 0x92, }, + { 44100, 0x02, 0x92, }, + { 48000, 0x04, 0x92, }, + { 64000, 0x08, 0x8e, }, + { 88200, 0x0a, 0x8e, }, + { 96000, 0x0c, 0x8e, }, + { 128000, 0x10, 0x8c, }, + { 176400, 0x12, 0x8c, }, + { 192000, 0x14, 0x8c, }, + }; + u32 data; + __le32 reg; + unsigned int count; + int i; + int err; + + for (i = 0; i < ARRAY_SIZE(rate_table); ++i) { + entry = rate_table + i; + if (entry->stf == rate) + break; + } + if (i == ARRAY_SIZE(rate_table)) + return -EINVAL; + + reg = cpu_to_le32(entry->code); + err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST, + LATTER_STF, ®, sizeof(reg), 0); + if (err < 0) + return err; + + // Confirm to shift transmission clock. + count = 0; + while (count++ < 10) { + unsigned int curr_rate; + enum snd_ff_clock_src src; + + err = latter_get_clock(ff, &curr_rate, &src); + if (err < 0) + return err; + + if (curr_rate == rate) + break; + } + if (count == 10) + return -ETIMEDOUT; + + err = keep_resources(ff, rate); + if (err < 0) + return err; + + data = (ff->tx_resources.channel << 8) | ff->rx_resources.channel; + reg = cpu_to_le32(data); + err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST, + LATTER_ISOC_CHANNELS, ®, sizeof(reg), 0); + if (err < 0) + return err; + + // Always use the maximum number of data channels in data block of + // packet. + reg = cpu_to_le32(entry->flag); + return snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST, + LATTER_ISOC_START, ®, sizeof(reg), 0); +} + +static void latter_finish_session(struct snd_ff *ff) +{ + __le32 reg; + + reg = cpu_to_le32(0x00000000); + snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST, + LATTER_ISOC_START, ®, sizeof(reg), 0); +} + +static void latter_dump_status(struct snd_ff *ff, struct snd_info_buffer *buffer) +{ + static const struct { + char *const label; + u32 locked_mask; + u32 synced_mask; + } *clk_entry, clk_entries[] = { + { "S/PDIF", 0x00000001, 0x00000010, }, + { "ADAT", 0x00000002, 0x00000020, }, + { "WDClk", 0x00000004, 0x00000040, }, + }; + __le32 reg; + u32 data; + unsigned int rate; + enum snd_ff_clock_src src; + const char *label; + int i; + int err; + + err = snd_fw_transaction(ff->unit, TCODE_READ_QUADLET_REQUEST, + LATTER_SYNC_STATUS, ®, sizeof(reg), 0); + if (err < 0) + return; + data = le32_to_cpu(reg); + + snd_iprintf(buffer, "External source detection:\n"); + + for (i = 0; i < ARRAY_SIZE(clk_entries); ++i) { + clk_entry = clk_entries + i; + snd_iprintf(buffer, "%s: ", clk_entry->label); + if (data & clk_entry->locked_mask) { + if (data & clk_entry->synced_mask) + snd_iprintf(buffer, "sync\n"); + else + snd_iprintf(buffer, "lock\n"); + } else { + snd_iprintf(buffer, "none\n"); + } + } + + err = parse_clock_bits(data, &rate, &src); + if (err < 0) + return; + label = snd_ff_proc_get_clk_label(src); + if (!label) + return; + + snd_iprintf(buffer, "Referred clock: %s %d\n", label, rate); +} + +const struct snd_ff_protocol snd_ff_protocol_latter = { + .get_clock = latter_get_clock, + .switch_fetching_mode = latter_switch_fetching_mode, + .begin_session = latter_begin_session, + .finish_session = latter_finish_session, + .dump_status = latter_dump_status, +}; diff --git a/sound/firewire/fireface/ff.c b/sound/firewire/fireface/ff.c index 36575f4159d1..fd9c980e3cf4 100644 --- a/sound/firewire/fireface/ff.c +++ b/sound/firewire/fireface/ff.c @@ -32,7 +32,8 @@ static void ff_card_free(struct snd_card *card) struct snd_ff *ff = card->private_data; snd_ff_stream_destroy_duplex(ff); - snd_ff_transaction_unregister(ff); + if (ff->spec->midi_high_addr > 0) + snd_ff_transaction_unregister(ff); } static void do_registration(struct work_struct *work) @@ -50,9 +51,11 @@ static void do_registration(struct work_struct *work) ff->card->private_free = ff_card_free; ff->card->private_data = ff; - err = snd_ff_transaction_register(ff); - if (err < 0) - goto error; + if (ff->spec->midi_high_addr > 0) { + err = snd_ff_transaction_register(ff); + if (err < 0) + goto error; + } name_card(ff); @@ -62,9 +65,11 @@ static void do_registration(struct work_struct *work) snd_ff_proc_init(ff); - err = snd_ff_create_midi_devices(ff); - if (err < 0) - goto error; + if (ff->spec->midi_in_ports > 0 || ff->spec->midi_out_ports > 0) { + err = snd_ff_create_midi_devices(ff); + if (err < 0) + goto error; + } err = snd_ff_create_pcm_devices(ff); if (err < 0) @@ -119,7 +124,8 @@ static void snd_ff_update(struct fw_unit *unit) if (!ff->registered) snd_fw_schedule_registration(unit, &ff->dwork); - snd_ff_transaction_reregister(ff); + if (ff->spec->midi_high_addr > 0) + snd_ff_transaction_reregister(ff); if (ff->registered) snd_ff_stream_update_duplex(ff); @@ -165,6 +171,13 @@ static const struct snd_ff_spec spec_ff400 = { .midi_high_addr = 0x0000801003f4ull, }; +static const struct snd_ff_spec spec_ucx = { + .name = "FirefaceUCX", + .pcm_capture_channels = {18, 14, 12}, + .pcm_playback_channels = {18, 14, 12}, + .protocol = &snd_ff_protocol_latter, +}; + static const struct ieee1394_device_id snd_ff_id_table[] = { /* Fireface 800 */ { @@ -190,6 +203,18 @@ static const struct ieee1394_device_id snd_ff_id_table[] = { .model_id = 0x101800, .driver_data = (kernel_ulong_t)&spec_ff400, }, + // Fireface UCX. + { + .match_flags = IEEE1394_MATCH_VENDOR_ID | + IEEE1394_MATCH_SPECIFIER_ID | + IEEE1394_MATCH_VERSION | + IEEE1394_MATCH_MODEL_ID, + .vendor_id = OUI_RME, + .specifier_id = OUI_RME, + .version = 0x000004, + .model_id = 0x101800, + .driver_data = (kernel_ulong_t)&spec_ucx, + }, {} }; MODULE_DEVICE_TABLE(ieee1394, snd_ff_id_table); diff --git a/sound/firewire/fireface/ff.h b/sound/firewire/fireface/ff.h index cdb16e931c31..8aea7920b57f 100644 --- a/sound/firewire/fireface/ff.h +++ b/sound/firewire/fireface/ff.h @@ -114,6 +114,7 @@ struct snd_ff_protocol { extern const struct snd_ff_protocol snd_ff_protocol_ff800; extern const struct snd_ff_protocol snd_ff_protocol_ff400; +extern const struct snd_ff_protocol snd_ff_protocol_latter; int snd_ff_transaction_register(struct snd_ff *ff); int snd_ff_transaction_reregister(struct snd_ff *ff);