From patchwork Fri Apr 25 13:44:51 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takashi Sakamoto X-Patchwork-Id: 4063081 X-Patchwork-Delegate: tiwai@suse.de Return-Path: X-Original-To: patchwork-alsa-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 03451BFF02 for ; Fri, 25 Apr 2014 14:12:56 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id CDD45203AA for ; Fri, 25 Apr 2014 14:12:54 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id 02D5E20398 for ; Fri, 25 Apr 2014 14:12:53 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id 06CAB265659; Fri, 25 Apr 2014 16:12:52 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from alsa0.perex.cz (localhost [IPv6:::1]) by alsa0.perex.cz (Postfix) with ESMTP id 99DE726565C; Fri, 25 Apr 2014 15:58:42 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 3133B26565B; Fri, 25 Apr 2014 15:58:41 +0200 (CEST) Received: from smtp310.phy.lolipop.jp (smtp310.phy.lolipop.jp [210.157.22.78]) by alsa0.perex.cz (Postfix) with ESMTP id 5EA4426548D for ; Fri, 25 Apr 2014 15:45:59 +0200 (CEST) Received: from smtp310.phy.lolipop.lan (HELO smtp310.phy.lolipop.jp) (172.17.1.10) (smtp-auth username m12129643-o-takashi, mechanism plain) by smtp310.phy.lolipop.jp (qpsmtpd/0.82) with ESMTPA; Fri, 25 Apr 2014 22:45:58 +0900 Received: from 127.0.0.1 (127.0.0.1) by smtp310.phy.lolipop.jp (LOLIPOP-Fsecure); Fri, 25 Apr 2014 22:45:31 +0900 (JST) X-Virus-Status: clean(LOLIPOP-Fsecure) From: Takashi Sakamoto To: clemens@ladisch.de, tiwai@suse.de, perex@perex.cz Date: Fri, 25 Apr 2014 22:44:51 +0900 Message-Id: <1398433530-13136-11-git-send-email-o-takashi@sakamocchi.jp> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1398433530-13136-1-git-send-email-o-takashi@sakamocchi.jp> References: <1398433530-13136-1-git-send-email-o-takashi@sakamocchi.jp> Cc: alsa-devel@alsa-project.org, linux1394-devel@lists.sourceforge.net, ffado-devel@lists.sf.net Subject: [alsa-devel] [PATCH 10/49] dice/firewire-lib: Keep dualwire mode but obsolete CIP_HI_DUALWIRE 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: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP In previous commit, AMDTP functionality in firewire-lib supports mapping for PCM data channels. With this mapping, firewire-lib can obsolete a flag, CIP_HI_DUALWIRE, but Dice driver still keeps dual wire mode. Signed-off-by: Takashi Sakamoto --- sound/firewire/amdtp.c | 151 ++----------------------------------------------- sound/firewire/amdtp.h | 8 +-- sound/firewire/dice.c | 33 +++++++++-- 3 files changed, 34 insertions(+), 158 deletions(-) diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c index 9cf81b2..3475b76 100644 --- a/sound/firewire/amdtp.c +++ b/sound/firewire/amdtp.c @@ -145,14 +145,7 @@ void amdtp_stream_set_parameters(struct amdtp_stream *s, return; sfc_found: - s->dual_wire = (s->flags & CIP_HI_DUALWIRE) && sfc > CIP_SFC_96000; - if (s->dual_wire) { - sfc -= 2; - rate /= 2; - s->pcm_channels = pcm_channels * 2; - } else { - s->pcm_channels = pcm_channels; - } + s->pcm_channels = pcm_channels; s->sfc = sfc; s->data_block_quadlets = s->pcm_channels + midi_channels; s->midi_ports = midi_ports; @@ -191,18 +184,9 @@ static void amdtp_write_s16(struct amdtp_stream *s, static void amdtp_write_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm, __be32 *buffer, unsigned int frames); -static void amdtp_write_s16_dualwire(struct amdtp_stream *s, - struct snd_pcm_substream *pcm, - __be32 *buffer, unsigned int frames); -static void amdtp_write_s32_dualwire(struct amdtp_stream *s, - struct snd_pcm_substream *pcm, - __be32 *buffer, unsigned int frames); static void amdtp_read_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm, __be32 *buffer, unsigned int frames); -static void amdtp_read_s32_dualwire(struct amdtp_stream *s, - struct snd_pcm_substream *pcm, - __be32 *buffer, unsigned int frames); /** * amdtp_stream_set_pcm_format - set the PCM format @@ -225,26 +209,16 @@ void amdtp_stream_set_pcm_format(struct amdtp_stream *s, /* fall through */ case SNDRV_PCM_FORMAT_S16: if (s->direction == AMDTP_OUT_STREAM) { - if (s->dual_wire) - s->transfer_samples = amdtp_write_s16_dualwire; - else - s->transfer_samples = amdtp_write_s16; + s->transfer_samples = amdtp_write_s16; break; } WARN_ON(1); /* fall through */ case SNDRV_PCM_FORMAT_S32: - if (s->direction == AMDTP_OUT_STREAM) { - if (s->dual_wire) - s->transfer_samples = amdtp_write_s32_dualwire; - else - s->transfer_samples = amdtp_write_s32; - } else { - if (s->dual_wire) - s->transfer_samples = amdtp_read_s32_dualwire; - else - s->transfer_samples = amdtp_read_s32; - } + if (s->direction == AMDTP_OUT_STREAM) + s->transfer_samples = amdtp_write_s32; + else + s->transfer_samples = amdtp_read_s32; break; } } @@ -393,68 +367,6 @@ static void amdtp_write_s16(struct amdtp_stream *s, } } -static void amdtp_write_s32_dualwire(struct amdtp_stream *s, - struct snd_pcm_substream *pcm, - __be32 *buffer, unsigned int frames) -{ - struct snd_pcm_runtime *runtime = pcm->runtime; - unsigned int channels, remaining_frames, i, c; - const u32 *src; - - src = (void *)runtime->dma_area + - frames_to_bytes(runtime, s->pcm_buffer_pointer); - remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer; - channels = s->pcm_channels / 2; - - for (i = 0; i < frames; ++i) { - for (c = 0; c < channels; ++c) { - buffer[s->pcm_positions[c] * 2] = - cpu_to_be32((*src >> 8) | 0x40000000); - src++; - } - buffer += 1; - for (c = 0; c < channels; ++c) { - buffer[s->pcm_positions[c] * 2] = - cpu_to_be32((*src >> 8) | 0x40000000); - src++; - } - buffer += s->data_block_quadlets - 1; - if (--remaining_frames == 0) - src = (void *)runtime->dma_area; - } -} - -static void amdtp_write_s16_dualwire(struct amdtp_stream *s, - struct snd_pcm_substream *pcm, - __be32 *buffer, unsigned int frames) -{ - struct snd_pcm_runtime *runtime = pcm->runtime; - unsigned int channels, remaining_frames, i, c; - const u16 *src; - - src = (void *)runtime->dma_area + - frames_to_bytes(runtime, s->pcm_buffer_pointer); - remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer; - channels = s->pcm_channels / 2; - - for (i = 0; i < frames; ++i) { - for (c = 0; c < channels; ++c) { - buffer[s->pcm_positions[c] * 2] = - cpu_to_be32((*src << 8) | 0x40000000); - src++; - } - buffer += 1; - for (c = 0; c < channels; ++c) { - buffer[s->pcm_positions[c] * 2] = - cpu_to_be32((*src << 8) | 0x40000000); - src++; - } - buffer += s->data_block_quadlets - 1; - if (--remaining_frames == 0) - src = (void *)runtime->dma_area; - } -} - static void amdtp_read_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm, __be32 *buffer, unsigned int frames) @@ -479,37 +391,6 @@ static void amdtp_read_s32(struct amdtp_stream *s, } } -static void amdtp_read_s32_dualwire(struct amdtp_stream *s, - struct snd_pcm_substream *pcm, - __be32 *buffer, unsigned int frames) -{ - struct snd_pcm_runtime *runtime = pcm->runtime; - unsigned int channels, remaining_frames, i, c; - u32 *dst; - - dst = (void *)runtime->dma_area + - frames_to_bytes(runtime, s->pcm_buffer_pointer); - remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer; - channels = s->pcm_channels / 2; - - for (i = 0; i < frames; ++i) { - for (c = 0; c < channels; ++c) { - *dst = - be32_to_cpu(buffer[s->pcm_positions[c] * 2]) << 8; - dst++; - } - buffer += 1; - for (c = 0; c < channels; ++c) { - *dst = - be32_to_cpu(buffer[s->pcm_positions[c] * 2]) << 8; - dst++; - } - buffer += s->data_block_quadlets - 1; - if (--remaining_frames == 0) - dst = (void *)runtime->dma_area; - } -} - static void amdtp_fill_pcm_silence(struct amdtp_stream *s, __be32 *buffer, unsigned int frames) { @@ -522,21 +403,6 @@ static void amdtp_fill_pcm_silence(struct amdtp_stream *s, } } -static void amdtp_fill_pcm_silence_dualwire(struct amdtp_stream *s, - __be32 *buffer, unsigned int frames) -{ - unsigned int i, c, channels; - - channels = s->pcm_channels / 2; - for (i = 0; i < frames; ++i) { - for (c = 0; c < channels; ++c) { - buffer[s->pcm_positions[c] * 2] = - buffer[s->pcm_positions[c] * 2 + 1] = - cpu_to_be32(0x40000000); - } - buffer += s->data_block_quadlets; - } -} static void amdtp_fill_midi(struct amdtp_stream *s, __be32 *buffer, unsigned int frames) { @@ -582,9 +448,6 @@ static void update_pcm_pointers(struct amdtp_stream *s, unsigned int frames) { unsigned int ptr; - if (s->dual_wire) - frames *= 2; - ptr = s->pcm_buffer_pointer + frames; if (ptr >= pcm->runtime->buffer_size) ptr -= pcm->runtime->buffer_size; @@ -674,8 +537,6 @@ static void handle_out_packet(struct amdtp_stream *s, unsigned int syt) pcm = ACCESS_ONCE(s->pcm); if (pcm) s->transfer_samples(s, pcm, buffer, data_blocks); - else if (s->dual_wire) - amdtp_fill_pcm_silence_dualwire(s, buffer, data_blocks); else amdtp_fill_pcm_silence(s, buffer, data_blocks); if (s->midi_ports) diff --git a/sound/firewire/amdtp.h b/sound/firewire/amdtp.h index e8d62ac..db60425 100644 --- a/sound/firewire/amdtp.h +++ b/sound/firewire/amdtp.h @@ -16,18 +16,13 @@ * @CIP_BLOCKING: In blocking mode, each packet contains either zero or * SYT_INTERVAL samples, with these two types alternating so that * the overall sample rate comes out right. - * @CIP_HI_DUALWIRE: At rates above 96 kHz, pretend that the stream runs - * at half the actual sample rate with twice the number of channels; - * two samples of a channel are stored consecutively in the packet. - * Requires blocking mode and SYT_INTERVAL-aligned PCM buffer size. * @CIP_SYNC_TO_DEVICE: In sync to device mode, time stamp in out packets is * generated by in packets. Defaultly this driver generates timestamp. */ enum cip_flags { CIP_NONBLOCKING = 0x00, CIP_BLOCKING = 0x01, - CIP_HI_DUALWIRE = 0x02, - CIP_SYNC_TO_DEVICE = 0x04, + CIP_SYNC_TO_DEVICE = 0x02, }; /** @@ -84,7 +79,6 @@ struct amdtp_stream { struct mutex mutex; enum cip_sfc sfc; - bool dual_wire; unsigned int data_block_quadlets; unsigned int pcm_channels; unsigned int midi_ports; diff --git a/sound/firewire/dice.c b/sound/firewire/dice.c index 26b2158..cd4c6b6 100644 --- a/sound/firewire/dice.c +++ b/sound/firewire/dice.c @@ -563,7 +563,7 @@ static int dice_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { struct dice *dice = substream->private_data; - unsigned int rate_index, mode; + unsigned int rate_index, mode, rate, channels, i; int err; mutex_lock(&dice->mutex); @@ -575,15 +575,36 @@ static int dice_hw_params(struct snd_pcm_substream *substream, if (err < 0) return err; - rate_index = rate_to_index(params_rate(hw_params)); + rate = params_rate(hw_params); + rate_index = rate_to_index(rate); err = dice_change_rate(dice, rate_index << CLOCK_RATE_SHIFT); if (err < 0) return err; + /* + * At rates above 96 kHz, pretend that the stream runs at half the + * actual sample rate with twice the number of channels; two samples + * of a channel are stored consecutively in the packet. Requires + * blocking mode and PCM buffer size should be aligned to SYT_INTERVAL. + */ + channels = params_channels(hw_params); + if (rate_index > 4) { + if (channels > AMDTP_MAX_CHANNELS_FOR_PCM / 2) { + err = -ENOSYS; + return err; + } + + for (i = 0; i < channels; i++) { + dice->stream.pcm_positions[i * 2] = i; + dice->stream.pcm_positions[i * 2 + 1] = i + channels; + } + + rate /= 2; + channels *= 2; + } + mode = rate_index_to_mode(rate_index); - amdtp_stream_set_parameters(&dice->stream, - params_rate(hw_params), - params_channels(hw_params), + amdtp_stream_set_parameters(&dice->stream, rate, channels, dice->rx_midi_ports[mode]); amdtp_stream_set_pcm_format(&dice->stream, params_format(hw_params)); @@ -1361,7 +1382,7 @@ static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id) dice->resources.channels_mask = 0x00000000ffffffffuLL; err = amdtp_stream_init(&dice->stream, unit, AMDTP_OUT_STREAM, - CIP_BLOCKING | CIP_HI_DUALWIRE); + CIP_BLOCKING); if (err < 0) goto err_resources;