ALSA: firewire-lib: add helper functions to set positions of data channels
[deliverable/linux.git] / sound / firewire / amdtp-am824.c
CommitLineData
5955815e
TS
1/*
2 * AM824 format in Audio and Music Data Transmission Protocol (IEC 61883-6)
3 *
4 * Copyright (c) 2015 Takashi Sakamoto <o-takashi@sakamocchi.jp>
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include "amdtp-am824.h"
10
11#define CIP_FMT_AM 0x10
12
51c29fd2
TS
13/* "Clock-based rate control mode" is just supported. */
14#define AMDTP_FDF_AM824 0x00
15
16/**
17 * amdtp_am824_set_parameters - set stream parameters
18 * @s: the AMDTP stream to configure
19 * @rate: the sample rate
20 * @pcm_channels: the number of PCM samples in each data block, to be encoded
21 * as AM824 multi-bit linear audio
22 * @midi_ports: the number of MIDI ports (i.e., MPX-MIDI Data Channels)
23 * @double_pcm_frames: one data block transfers two PCM frames
24 *
25 * The parameters must be set before the stream is started, and must not be
26 * changed while the stream is running.
27 */
28int amdtp_am824_set_parameters(struct amdtp_stream *s, unsigned int rate,
29 unsigned int pcm_channels,
30 unsigned int midi_ports,
31 bool double_pcm_frames)
32{
33 int err;
34
35 err = amdtp_stream_set_parameters(s, rate, pcm_channels, midi_ports);
36 if (err < 0)
37 return err;
38
39 s->fdf = AMDTP_FDF_AM824 | s->sfc;
40
41 /*
42 * In IEC 61883-6, one data block represents one event. In ALSA, one
43 * event equals to one PCM frame. But Dice has a quirk at higher
44 * sampling rate to transfer two PCM frames in one data block.
45 */
46 if (double_pcm_frames)
47 s->frame_multiplier = 2;
48 else
49 s->frame_multiplier = 1;
50
51 return 0;
52}
53EXPORT_SYMBOL_GPL(amdtp_am824_set_parameters);
54
f65be911
TS
55/**
56 * amdtp_am824_set_pcm_position - set an index of data channel for a channel
57 * of PCM frame
58 * @s: the AMDTP stream
59 * @index: the index of data channel in an data block
60 * @position: the channel of PCM frame
61 */
62void amdtp_am824_set_pcm_position(struct amdtp_stream *s, unsigned int index,
63 unsigned int position)
64{
65 if (index < s->pcm_channels)
66 s->pcm_positions[index] = position;
67}
68EXPORT_SYMBOL_GPL(amdtp_am824_set_pcm_position);
69
70/**
71 * amdtp_am824_set_midi_position - set a index of data channel for MIDI
72 * conformant data channel
73 * @s: the AMDTP stream
74 * @position: the index of data channel in an data block
75 */
76void amdtp_am824_set_midi_position(struct amdtp_stream *s,
77 unsigned int position)
78{
79 s->midi_position = position;
80}
81EXPORT_SYMBOL_GPL(amdtp_am824_set_midi_position);
82
bc8500da
TS
83/**
84 * amdtp_am824_add_pcm_hw_constraints - add hw constraints for PCM substream
85 * @s: the AMDTP stream for AM824 data block, must be initialized.
86 * @runtime: the PCM substream runtime
87 *
88 */
89int amdtp_am824_add_pcm_hw_constraints(struct amdtp_stream *s,
90 struct snd_pcm_runtime *runtime)
91{
92 int err;
93
94 err = amdtp_stream_add_pcm_hw_constraints(s, runtime);
95 if (err < 0)
96 return err;
97
98 /* AM824 in IEC 61883-6 can deliver 24bit data. */
99 return snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
100}
101EXPORT_SYMBOL_GPL(amdtp_am824_add_pcm_hw_constraints);
102
5955815e
TS
103/**
104 * amdtp_am824_init - initialize an AMDTP stream structure to handle AM824
105 * data block
106 * @s: the AMDTP stream to initialize
107 * @unit: the target of the stream
108 * @dir: the direction of stream
109 * @flags: the packet transmission method to use
110 */
111int amdtp_am824_init(struct amdtp_stream *s, struct fw_unit *unit,
112 enum amdtp_stream_direction dir, enum cip_flags flags)
113{
114 return amdtp_stream_init(s, unit, dir, flags, CIP_FMT_AM);
115}
116EXPORT_SYMBOL_GPL(amdtp_am824_init);
This page took 0.027705 seconds and 5 git commands to generate.