ALSA: firewire-motu: parse messages for input parameters in register DSP model
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Fri, 15 Oct 2021 08:08:23 +0000 (17:08 +0900)
committerTakashi Iwai <tiwai@suse.de>
Fri, 15 Oct 2021 15:52:14 +0000 (17:52 +0200)
This commit parses message and cache current parameters of input function,
available for MOTU Ultralite, 4 pre, and Audio Express.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Link: https://lore.kernel.org/r/20211015080826.34847-9-o-takashi@sakamocchi.jp
Signed-off-by: Takashi Iwai <tiwai@suse.de>
include/uapi/sound/firewire.h
sound/firewire/motu/motu-register-dsp-message-parser.c

index 049934e2a53cfb482f91ea6ead77c66620fb1a03..6366127e923e86a1cbb094fdfc86660fddfba218 100644 (file)
@@ -147,6 +147,8 @@ struct snd_firewire_motu_register_dsp_meter {
 
 #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
@@ -168,6 +170,11 @@ struct snd_firewire_motu_register_dsp_meter {
  * @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.
  */
@@ -196,6 +203,11 @@ struct snd_firewire_motu_register_dsp_parameter {
                __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
index 85faf7a4e8a390f405a8cd3876f360776458fc3e..d94ca4875714e76deeb1e523a18a973ceed27443 100644 (file)
@@ -87,6 +87,9 @@ struct msg_parser {
        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)
@@ -109,6 +112,7 @@ int snd_motu_register_dsp_message_parser_init(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;
 }
@@ -225,6 +229,35 @@ void snd_motu_register_dsp_message_parser_parse(struct snd_motu *motu, const str
                        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;
@@ -239,11 +272,17 @@ void snd_motu_register_dsp_message_parser_parse(struct snd_motu *motu, const str
                                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;
                }
        }