Skip to content

Commit

Permalink
ALSA: dice: disable double_pcm_frames mode for M-Audio Profire 610, 2…
Browse files Browse the repository at this point in the history
…626 and Avid M-Box 3 Pro

[ Upstream commit 9f079c1 ]

ALSA dice driver detects jumbo payload at high sampling transfer frequency
for below models:

 * Avid M-Box 3 Pro
 * M-Audio Profire 610
 * M-Audio Profire 2626

Although many DICE-based devices have a quirk at high sampling transfer
frequency to multiplex double number of PCM frames into data block than
the number in IEC 61883-1/6, the above devices are just compliant to
IEC 61883-1/6.

This commit disables the mode of double_pcm_frames for the models.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Link: https://lore.kernel.org/r/20210518012510.37126-1-o-takashi@sakamocchi.jp
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
takaswie authored and gregkh committed Jun 3, 2021
1 parent b545442 commit dc720b1
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 4 deletions.
4 changes: 2 additions & 2 deletions sound/firewire/dice/dice-pcm.c
Expand Up @@ -218,7 +218,7 @@ static int pcm_open(struct snd_pcm_substream *substream)

if (frames_per_period > 0) {
// For double_pcm_frame quirk.
if (rate > 96000) {
if (rate > 96000 && !dice->disable_double_pcm_frames) {
frames_per_period *= 2;
frames_per_buffer *= 2;
}
Expand Down Expand Up @@ -273,7 +273,7 @@ static int pcm_hw_params(struct snd_pcm_substream *substream,

mutex_lock(&dice->mutex);
// For double_pcm_frame quirk.
if (rate > 96000) {
if (rate > 96000 && !dice->disable_double_pcm_frames) {
events_per_period /= 2;
events_per_buffer /= 2;
}
Expand Down
2 changes: 1 addition & 1 deletion sound/firewire/dice/dice-stream.c
Expand Up @@ -181,7 +181,7 @@ static int keep_resources(struct snd_dice *dice, struct amdtp_stream *stream,
// as 'Dual Wire'.
// For this quirk, blocking mode is required and PCM buffer size should
// be aligned to SYT_INTERVAL.
double_pcm_frames = rate > 96000;
double_pcm_frames = (rate > 96000 && !dice->disable_double_pcm_frames);
if (double_pcm_frames) {
rate /= 2;
pcm_chs *= 2;
Expand Down
24 changes: 24 additions & 0 deletions sound/firewire/dice/dice.c
Expand Up @@ -21,6 +21,7 @@ MODULE_LICENSE("GPL v2");
#define OUI_SSL 0x0050c2 // Actually ID reserved by IEEE.
#define OUI_PRESONUS 0x000a92
#define OUI_HARMAN 0x000fd7
#define OUI_AVID 0x00a07e

#define DICE_CATEGORY_ID 0x04
#define WEISS_CATEGORY_ID 0x00
Expand Down Expand Up @@ -222,6 +223,14 @@ static int dice_probe(struct fw_unit *unit,
(snd_dice_detect_formats_t)entry->driver_data;
}

// Below models are compliant to IEC 61883-1/6 and have no quirk at high sampling transfer
// frequency.
// * Avid M-Box 3 Pro
// * M-Audio Profire 610
// * M-Audio Profire 2626
if (entry->vendor_id == OUI_MAUDIO || entry->vendor_id == OUI_AVID)
dice->disable_double_pcm_frames = true;

spin_lock_init(&dice->lock);
mutex_init(&dice->mutex);
init_completion(&dice->clock_accepted);
Expand Down Expand Up @@ -278,7 +287,22 @@ static void dice_bus_reset(struct fw_unit *unit)

#define DICE_INTERFACE 0x000001

#define DICE_DEV_ENTRY_TYPICAL(vendor, model, data) \
{ \
.match_flags = IEEE1394_MATCH_VENDOR_ID | \
IEEE1394_MATCH_MODEL_ID | \
IEEE1394_MATCH_SPECIFIER_ID | \
IEEE1394_MATCH_VERSION, \
.vendor_id = (vendor), \
.model_id = (model), \
.specifier_id = (vendor), \
.version = DICE_INTERFACE, \
.driver_data = (kernel_ulong_t)(data), \
}

static const struct ieee1394_device_id dice_id_table[] = {
// Avid M-Box 3 Pro. To match in probe function.
DICE_DEV_ENTRY_TYPICAL(OUI_AVID, 0x000004, snd_dice_detect_extension_formats),
/* M-Audio Profire 2626 has a different value in version field. */
{
.match_flags = IEEE1394_MATCH_VENDOR_ID |
Expand Down
3 changes: 2 additions & 1 deletion sound/firewire/dice/dice.h
Expand Up @@ -109,7 +109,8 @@ struct snd_dice {
struct fw_iso_resources rx_resources[MAX_STREAMS];
struct amdtp_stream tx_stream[MAX_STREAMS];
struct amdtp_stream rx_stream[MAX_STREAMS];
bool global_enabled;
bool global_enabled:1;
bool disable_double_pcm_frames:1;
struct completion clock_accepted;
unsigned int substreams_counter;

Expand Down

0 comments on commit dc720b1

Please sign in to comment.