diff options
author | Takashi Sakamoto <o-takashi@sakamocchi.jp> | 2018-12-16 17:32:29 +0900 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2018-12-16 10:18:23 +0100 |
commit | d4a0b6cbf26ce7c22bcb070595957590736fec85 (patch) | |
tree | 01b3b3a506d9176c57cb5e8e72623a54d3626967 /sound/firewire/fireface/ff-stream.c | |
parent | 3d16200a3e55a39caa1c88419cb559c00316f721 (diff) |
ALSA: fireface: share helper function to switch fetching mode
Both of Fireface 400/800 have the same register to switch frame fetching
mode regardless of difference of available number of PCM frames in
rx isochronous packet.
This commit moves a helper function from model-dependent implementation.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/firewire/fireface/ff-stream.c')
-rw-r--r-- | sound/firewire/fireface/ff-stream.c | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/sound/firewire/fireface/ff-stream.c b/sound/firewire/fireface/ff-stream.c index 59ca2e84d41c..e6fa6362dab7 100644 --- a/sound/firewire/fireface/ff-stream.c +++ b/sound/firewire/fireface/ff-stream.c @@ -73,10 +73,44 @@ static void release_resources(struct snd_ff *ff) fw_iso_resources_free(&ff->rx_resources); } +static int switch_fetching_mode(struct snd_ff *ff, bool enable) +{ + unsigned int count; + __le32 *reg; + int i; + int err; + + count = 0; + for (i = 0; i < SND_FF_STREAM_MODES; ++i) + count = max(count, ff->spec->pcm_playback_channels[i]); + + reg = kcalloc(count, sizeof(__le32), GFP_KERNEL); + if (!reg) + return -ENOMEM; + + if (!enable) { + /* + * Each quadlet is corresponding to data channels in a data + * blocks in reverse order. Precisely, quadlets for available + * data channels should be enabled. Here, I take second best + * to fetch PCM frames from all of data channels regardless of + * stf. + */ + for (i = 0; i < count; ++i) + reg[i] = cpu_to_le32(0x00000001); + } + + err = snd_fw_transaction(ff->unit, TCODE_WRITE_BLOCK_REQUEST, + SND_FF_REG_FETCH_PCM_FRAMES, reg, + sizeof(__le32) * count, 0); + kfree(reg); + return err; +} + static inline void finish_session(struct snd_ff *ff) { ff->spec->protocol->finish_session(ff); - ff->spec->protocol->switch_fetching_mode(ff, false); + switch_fetching_mode(ff, false); } static int init_stream(struct snd_ff *ff, enum amdtp_stream_direction dir) @@ -188,7 +222,7 @@ int snd_ff_stream_start_duplex(struct snd_ff *ff, unsigned int rate) goto error; } - err = ff->spec->protocol->switch_fetching_mode(ff, true); + err = switch_fetching_mode(ff, true); if (err < 0) goto error; } |