Commit 76ea4688 authored by Takashi Sakamoto's avatar Takashi Sakamoto Committed by Takashi Iwai

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: default avatarTakashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent d4a0b6cb
...@@ -8,11 +8,6 @@ ...@@ -8,11 +8,6 @@
#include "ff.h" #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, static int hw_rule_rate(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule) struct snd_pcm_hw_rule *rule)
{ {
...@@ -24,10 +19,16 @@ static int hw_rule_rate(struct snd_pcm_hw_params *params, ...@@ -24,10 +19,16 @@ static int hw_rule_rate(struct snd_pcm_hw_params *params,
struct snd_interval t = { struct snd_interval t = {
.min = UINT_MAX, .max = 0, .integer = 1 .min = UINT_MAX, .max = 0, .integer = 1
}; };
unsigned int i, mode; unsigned int i;
for (i = 0; i < ARRAY_SIZE(amdtp_rate_table); 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])) if (!snd_interval_test(c, pcm_channels[mode]))
continue; continue;
...@@ -49,10 +50,16 @@ static int hw_rule_channels(struct snd_pcm_hw_params *params, ...@@ -49,10 +50,16 @@ static int hw_rule_channels(struct snd_pcm_hw_params *params,
struct snd_interval t = { struct snd_interval t = {
.min = UINT_MAX, .max = 0, .integer = 1 .min = UINT_MAX, .max = 0, .integer = 1
}; };
unsigned int i, mode; unsigned int i;
for (i = 0; i < ARRAY_SIZE(amdtp_rate_table); 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])) if (!snd_interval_test(r, amdtp_rate_table[i]))
continue; continue;
...@@ -66,7 +73,6 @@ static int hw_rule_channels(struct snd_pcm_hw_params *params, ...@@ -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, static void limit_channels_and_rates(struct snd_pcm_hardware *hw,
const unsigned int *pcm_channels) const unsigned int *pcm_channels)
{ {
unsigned int mode;
unsigned int rate, channels; unsigned int rate, channels;
int i; int i;
...@@ -76,7 +82,12 @@ static void limit_channels_and_rates(struct snd_pcm_hardware *hw, ...@@ -76,7 +82,12 @@ static void limit_channels_and_rates(struct snd_pcm_hardware *hw,
hw->rate_max = 0; hw->rate_max = 0;
for (i = 0; i < ARRAY_SIZE(amdtp_rate_table); 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;
channels = pcm_channels[mode]; channels = pcm_channels[mode];
if (pcm_channels[mode] == 0) if (pcm_channels[mode] == 0)
......
...@@ -10,19 +10,23 @@ ...@@ -10,19 +10,23 @@
#define CALLBACK_TIMEOUT_MS 200 #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; static const enum snd_ff_stream_mode modes[] = {
[CIP_SFC_32000] = SND_FF_STREAM_MODE_LOW,
for (i = 0; i < CIP_SFC_COUNT; i++) { [CIP_SFC_44100] = SND_FF_STREAM_MODE_LOW,
if (amdtp_rate_table[i] == rate) [CIP_SFC_48000] = SND_FF_STREAM_MODE_LOW,
break; [CIP_SFC_88200] = SND_FF_STREAM_MODE_MID,
} [CIP_SFC_96000] = SND_FF_STREAM_MODE_MID,
[CIP_SFC_176400] = SND_FF_STREAM_MODE_HIGH,
if (i == CIP_SFC_COUNT) [CIP_SFC_192000] = SND_FF_STREAM_MODE_HIGH,
};
if (sfc >= CIP_SFC_COUNT)
return -EINVAL; return -EINVAL;
*mode = ((int)i - 1) / 2; *mode = modes[sfc];
return 0; return 0;
} }
...@@ -33,10 +37,18 @@ static int get_rate_mode(unsigned int rate, unsigned int *mode) ...@@ -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) static int keep_resources(struct snd_ff *ff, unsigned int rate)
{ {
int mode; enum snd_ff_stream_mode mode;
int i;
int err; 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) if (err < 0)
return err; return err;
...@@ -81,7 +93,7 @@ static int switch_fetching_mode(struct snd_ff *ff, bool enable) ...@@ -81,7 +93,7 @@ static int switch_fetching_mode(struct snd_ff *ff, bool enable)
int err; int err;
count = 0; 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]); count = max(count, ff->spec->pcm_playback_channels[i]);
reg = kcalloc(count, sizeof(__le32), GFP_KERNEL); reg = kcalloc(count, sizeof(__le32), GFP_KERNEL);
......
...@@ -31,8 +31,6 @@ ...@@ -31,8 +31,6 @@
#include "../amdtp-stream.h" #include "../amdtp-stream.h"
#include "../iso-resources.h" #include "../iso-resources.h"
#define SND_FF_STREAM_MODES 3
#define SND_FF_MAXIMIM_MIDI_QUADS 9 #define SND_FF_MAXIMIM_MIDI_QUADS 9
#define SND_FF_IN_MIDI_PORTS 2 #define SND_FF_IN_MIDI_PORTS 2
#define SND_FF_OUT_MIDI_PORTS 2 #define SND_FF_OUT_MIDI_PORTS 2
...@@ -42,6 +40,13 @@ ...@@ -42,6 +40,13 @@
#define SND_FF_REG_FETCH_PCM_FRAMES 0x0000801c0000ull #define SND_FF_REG_FETCH_PCM_FRAMES 0x0000801c0000ull
#define SND_FF_REG_CLOCK_CONFIG 0x0000801c0004ull #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 { enum snd_ff_reg_type {
SND_FF_REG_TYPE_MIDI_HIGH_ADDR = 0, SND_FF_REG_TYPE_MIDI_HIGH_ADDR = 0,
SND_FF_REG_TYPE_COUNT, SND_FF_REG_TYPE_COUNT,
...@@ -51,8 +56,8 @@ struct snd_ff_protocol; ...@@ -51,8 +56,8 @@ struct snd_ff_protocol;
struct snd_ff_spec { struct snd_ff_spec {
const char *const name; const char *const name;
const unsigned int pcm_capture_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_MODES]; const unsigned int pcm_playback_channels[SND_FF_STREAM_MODE_COUNT];
unsigned int midi_in_ports; unsigned int midi_in_ports;
unsigned int midi_out_ports; unsigned int midi_out_ports;
...@@ -129,6 +134,8 @@ int amdtp_ff_add_pcm_hw_constraints(struct amdtp_stream *s, ...@@ -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, int amdtp_ff_init(struct amdtp_stream *s, struct fw_unit *unit,
enum amdtp_stream_direction dir); 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); int snd_ff_stream_init_duplex(struct snd_ff *ff);
void snd_ff_stream_destroy_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); int snd_ff_stream_start_duplex(struct snd_ff *ff, unsigned int rate);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment