#define SNDRV_FIREWIRE_MOTU_REGISTER_DSP_MIXER_COUNT 4
#define SNDRV_FIREWIRE_MOTU_REGISTER_DSP_MIXER_SRC_COUNT 20
+#define SNDRV_FIREWIRE_MOTU_REGISTER_DSP_INPUT_COUNT 10
+#define SNDRV_FIREWIRE_MOTU_REGISTER_DSP_ALIGNED_INPUT_COUNT (SNDRV_FIREWIRE_MOTU_REGISTER_DSP_INPUT_COUNT + 2)
/**
* snd_firewire_motu_register_dsp_parameter - the container for parameters of DSP controlled
* @line_input.nominal_level_flag: The flags of nominal level for line inputs, only for 828mk2 and
* Traveler.
* @line_input.reserved: Padding for 32 bit alignment for future extension.
+ * @input.gain_and_invert: The value including gain and invert for input, only for Ultralite, 4 pre
+ * and Audio Express.
+ * @input.flag: The flag of input; e.g. jack detection, phantom power, and pad, only for Ultralite,
+ * 4 pre and Audio express.
+ * @reserved: Padding so that the size of structure is kept to 512 byte, but for future extension.
*
* The structure expresses the set of parameters for DSP controlled by register access.
*/
__u8 nominal_level_flag;
__u8 reserved[6];
} line_input;
+ struct {
+ __u8 gain_and_invert[SNDRV_FIREWIRE_MOTU_REGISTER_DSP_ALIGNED_INPUT_COUNT];
+ __u8 flag[SNDRV_FIREWIRE_MOTU_REGISTER_DSP_ALIGNED_INPUT_COUNT];
+ } input;
+ __u8 reserved[64];
};
// In below MOTU models, software is allowed to control their DSP by command in frame of
u8 prev_mixer_src_type;
u8 mixer_ch;
u8 mixer_src_ch;
+
+ u8 input_ch;
+ u8 prev_msg_type;
};
int snd_motu_register_dsp_message_parser_new(struct snd_motu *motu)
parser->prev_mixer_src_type = INVALID;
parser->mixer_ch = 0xff;
parser->mixer_src_ch = 0xff;
+ parser->prev_msg_type = INVALID;
return 0;
}
case LINE_INPUT_NOMINAL_LEVEL:
parser->param.line_input.nominal_level_flag = val;
break;
+ case INPUT_GAIN_AND_INVERT:
+ case INPUT_FLAG:
+ {
+ struct snd_firewire_motu_register_dsp_parameter *param = &parser->param;
+ u8 input_ch = parser->input_ch;
+
+ if (parser->prev_msg_type != msg_type)
+ input_ch = 0;
+ else
+ ++input_ch;
+
+ if (input_ch < SNDRV_FIREWIRE_MOTU_REGISTER_DSP_INPUT_COUNT) {
+ switch (msg_type) {
+ case INPUT_GAIN_AND_INVERT:
+ param->input.gain_and_invert[input_ch] = val;
+ break;
+ case INPUT_FLAG:
+ param->input.flag[input_ch] = val;
+ break;
+ default:
+ break;
+ }
+ parser->input_ch = input_ch;
+ }
+ break;
+ }
+ case UNKNOWN_0:
+ case UNKNOWN_2:
+ break;
case METER:
{
u8 pos;
else
pos = (pos & 0x1f) + 20;
parser->meter.data[pos] = val;
- break;
+ // The message for meter is interruptible to the series of other
+ // types of messages. Don't cache it.
+ fallthrough;
}
+ case INVALID:
default:
- break;
+ // Don't cache it.
+ continue;
}
+
+ parser->prev_msg_type = msg_type;
}
}