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 <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Родитель
d4a0b6cbf2
Коммит
76ea468877
|
@ -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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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 @@
|
||||||
|
|
||||||
#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,
|
||||||
|
[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,
|
||||||
|
};
|
||||||
|
|
||||||
for (i = 0; i < CIP_SFC_COUNT; i++) {
|
if (sfc >= CIP_SFC_COUNT)
|
||||||
if (amdtp_rate_table[i] == rate)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i == 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)
|
||||||
*/
|
*/
|
||||||
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)
|
||||||
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 @@
|
||||||
#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 @@
|
||||||
#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;
|
||||||
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,
|
||||||
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);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче