From 76ea46887729d0765b1fd39291a69c2c6781ada0 Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Sun, 16 Dec 2018 17:32:30 +0900 Subject: ALSA: fireface: code refactoring to handle multiplier mode Fireface 400/800 use three modes against the number of data channels in data block for both tx/rx packets. This commit adds refactoring for it. Some enumerators are added to represent each of mode and a function is added to calculate the mode from sampling frequency code (sfc). Signed-off-by: Takashi Sakamoto Signed-off-by: Takashi Iwai --- sound/firewire/fireface/ff-pcm.c | 33 +++++++++++++++++++++----------- sound/firewire/fireface/ff-stream.c | 38 ++++++++++++++++++++++++------------- sound/firewire/fireface/ff.h | 15 +++++++++++---- 3 files changed, 58 insertions(+), 28 deletions(-) (limited to 'sound/firewire') diff --git a/sound/firewire/fireface/ff-pcm.c b/sound/firewire/fireface/ff-pcm.c index 63b0be6f05e8..d0bc96b20a65 100644 --- a/sound/firewire/fireface/ff-pcm.c +++ b/sound/firewire/fireface/ff-pcm.c @@ -8,11 +8,6 @@ #include "ff.h" -static inline unsigned int get_multiplier_mode_with_index(unsigned int index) -{ - return ((int)index - 1) / 2; -} - static int hw_rule_rate(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) { @@ -24,10 +19,16 @@ static int hw_rule_rate(struct snd_pcm_hw_params *params, struct snd_interval t = { .min = UINT_MAX, .max = 0, .integer = 1 }; - unsigned int i, mode; + unsigned int i; for (i = 0; i < ARRAY_SIZE(amdtp_rate_table); i++) { - mode = get_multiplier_mode_with_index(i); + enum snd_ff_stream_mode mode; + int err; + + err = snd_ff_stream_get_multiplier_mode(i, &mode); + if (err < 0) + continue; + if (!snd_interval_test(c, pcm_channels[mode])) continue; @@ -49,10 +50,16 @@ static int hw_rule_channels(struct snd_pcm_hw_params *params, struct snd_interval t = { .min = UINT_MAX, .max = 0, .integer = 1 }; - unsigned int i, mode; + unsigned int i; for (i = 0; i < ARRAY_SIZE(amdtp_rate_table); i++) { - mode = get_multiplier_mode_with_index(i); + enum snd_ff_stream_mode mode; + int err; + + err = snd_ff_stream_get_multiplier_mode(i, &mode); + if (err < 0) + continue; + if (!snd_interval_test(r, amdtp_rate_table[i])) continue; @@ -66,7 +73,6 @@ static int hw_rule_channels(struct snd_pcm_hw_params *params, static void limit_channels_and_rates(struct snd_pcm_hardware *hw, const unsigned int *pcm_channels) { - unsigned int mode; unsigned int rate, channels; int i; @@ -76,7 +82,12 @@ static void limit_channels_and_rates(struct snd_pcm_hardware *hw, hw->rate_max = 0; for (i = 0; i < ARRAY_SIZE(amdtp_rate_table); i++) { - mode = get_multiplier_mode_with_index(i); + enum snd_ff_stream_mode mode; + int err; + + err = snd_ff_stream_get_multiplier_mode(i, &mode); + if (err < 0) + continue; channels = pcm_channels[mode]; if (pcm_channels[mode] == 0) diff --git a/sound/firewire/fireface/ff-stream.c b/sound/firewire/fireface/ff-stream.c index e6fa6362dab7..e6a8229a9d82 100644 --- a/sound/firewire/fireface/ff-stream.c +++ b/sound/firewire/fireface/ff-stream.c @@ -10,19 +10,23 @@ #define CALLBACK_TIMEOUT_MS 200 -static int get_rate_mode(unsigned int rate, unsigned int *mode) +int snd_ff_stream_get_multiplier_mode(enum cip_sfc sfc, + enum snd_ff_stream_mode *mode) { - int i; - - for (i = 0; i < CIP_SFC_COUNT; i++) { - if (amdtp_rate_table[i] == rate) - break; - } - - if (i == CIP_SFC_COUNT) + static const enum snd_ff_stream_mode modes[] = { + [CIP_SFC_32000] = SND_FF_STREAM_MODE_LOW, + [CIP_SFC_44100] = SND_FF_STREAM_MODE_LOW, + [CIP_SFC_48000] = SND_FF_STREAM_MODE_LOW, + [CIP_SFC_88200] = SND_FF_STREAM_MODE_MID, + [CIP_SFC_96000] = SND_FF_STREAM_MODE_MID, + [CIP_SFC_176400] = SND_FF_STREAM_MODE_HIGH, + [CIP_SFC_192000] = SND_FF_STREAM_MODE_HIGH, + }; + + if (sfc >= CIP_SFC_COUNT) return -EINVAL; - *mode = ((int)i - 1) / 2; + *mode = modes[sfc]; return 0; } @@ -33,10 +37,18 @@ static int get_rate_mode(unsigned int rate, unsigned int *mode) */ static int keep_resources(struct snd_ff *ff, unsigned int rate) { - int mode; + enum snd_ff_stream_mode mode; + int i; int err; - err = get_rate_mode(rate, &mode); + 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; @@ -81,7 +93,7 @@ static int switch_fetching_mode(struct snd_ff *ff, bool enable) int err; count = 0; - for (i = 0; i < SND_FF_STREAM_MODES; ++i) + 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); diff --git a/sound/firewire/fireface/ff.h b/sound/firewire/fireface/ff.h index 17332d9ae3f2..9fdda4fbdbba 100644 --- a/sound/firewire/fireface/ff.h +++ b/sound/firewire/fireface/ff.h @@ -31,8 +31,6 @@ #include "../amdtp-stream.h" #include "../iso-resources.h" -#define SND_FF_STREAM_MODES 3 - #define SND_FF_MAXIMIM_MIDI_QUADS 9 #define SND_FF_IN_MIDI_PORTS 2 #define SND_FF_OUT_MIDI_PORTS 2 @@ -42,6 +40,13 @@ #define SND_FF_REG_FETCH_PCM_FRAMES 0x0000801c0000ull #define SND_FF_REG_CLOCK_CONFIG 0x0000801c0004ull +enum snd_ff_stream_mode { + SND_FF_STREAM_MODE_LOW = 0, + SND_FF_STREAM_MODE_MID, + SND_FF_STREAM_MODE_HIGH, + SND_FF_STREAM_MODE_COUNT, +}; + enum snd_ff_reg_type { SND_FF_REG_TYPE_MIDI_HIGH_ADDR = 0, SND_FF_REG_TYPE_COUNT, @@ -51,8 +56,8 @@ struct snd_ff_protocol; struct snd_ff_spec { const char *const name; - const unsigned int pcm_capture_channels[SND_FF_STREAM_MODES]; - const unsigned int pcm_playback_channels[SND_FF_STREAM_MODES]; + const unsigned int pcm_capture_channels[SND_FF_STREAM_MODE_COUNT]; + const unsigned int pcm_playback_channels[SND_FF_STREAM_MODE_COUNT]; unsigned int midi_in_ports; unsigned int midi_out_ports; @@ -129,6 +134,8 @@ int amdtp_ff_add_pcm_hw_constraints(struct amdtp_stream *s, int amdtp_ff_init(struct amdtp_stream *s, struct fw_unit *unit, enum amdtp_stream_direction dir); +int snd_ff_stream_get_multiplier_mode(enum cip_sfc sfc, + enum snd_ff_stream_mode *mode); int snd_ff_stream_init_duplex(struct snd_ff *ff); void snd_ff_stream_destroy_duplex(struct snd_ff *ff); int snd_ff_stream_start_duplex(struct snd_ff *ff, unsigned int rate); -- cgit