~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/firewire/motu/motu-command-dsp-message-parser.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /sound/firewire/motu/motu-command-dsp-message-parser.c (Version linux-6.12-rc7) and /sound/firewire/motu/motu-command-dsp-message-parser.c (Version linux-6.1.116)


  1 // SPDX-License-Identifier: GPL-2.0-only            1 // SPDX-License-Identifier: GPL-2.0-only
  2 //                                                  2 //
  3 // motu-command-dsp-message-parser.c - a part       3 // motu-command-dsp-message-parser.c - a part of driver for MOTU FireWire series
  4 //                                                  4 //
  5 // Copyright (c) 2021 Takashi Sakamoto <o-taka      5 // Copyright (c) 2021 Takashi Sakamoto <o-takashi@sakamocchi.jp>
  6                                                     6 
  7 // Below models allow software to configure th      7 // Below models allow software to configure their DSP function by command transferred in
  8 // asynchronous transaction:                        8 // asynchronous transaction:
  9 //  * 828 mk3 (FireWire only and Hybrid)            9 //  * 828 mk3 (FireWire only and Hybrid)
 10 //  * 896 mk3 (FireWire only and Hybrid)           10 //  * 896 mk3 (FireWire only and Hybrid)
 11 //  * Ultralite mk3 (FireWire only and Hybrid)     11 //  * Ultralite mk3 (FireWire only and Hybrid)
 12 //  * Traveler mk3                                 12 //  * Traveler mk3
 13 //  * Track 16                                     13 //  * Track 16
 14 //                                                 14 //
 15 // Isochronous packets from the above models i     15 // Isochronous packets from the above models includes messages to report state of hardware meter.
 16                                                    16 
 17 #include "motu.h"                                  17 #include "motu.h"
 18                                                    18 
 19 enum msg_parser_state {                            19 enum msg_parser_state {
 20         INITIALIZED,                               20         INITIALIZED,
 21         FRAGMENT_DETECTED,                         21         FRAGMENT_DETECTED,
 22         AVAILABLE,                                 22         AVAILABLE,
 23 };                                                 23 };
 24                                                    24 
 25 struct msg_parser {                                25 struct msg_parser {
 26         spinlock_t lock;                           26         spinlock_t lock;
 27         enum msg_parser_state state;               27         enum msg_parser_state state;
 28         unsigned int interval;                     28         unsigned int interval;
 29         unsigned int message_count;                29         unsigned int message_count;
 30         unsigned int fragment_pos;                 30         unsigned int fragment_pos;
 31         unsigned int value_index;                  31         unsigned int value_index;
 32         u64 value;                                 32         u64 value;
 33         struct snd_firewire_motu_command_dsp_m     33         struct snd_firewire_motu_command_dsp_meter meter;
 34 };                                                 34 };
 35                                                    35 
 36 int snd_motu_command_dsp_message_parser_new(st     36 int snd_motu_command_dsp_message_parser_new(struct snd_motu *motu)
 37 {                                                  37 {
 38         struct msg_parser *parser;                 38         struct msg_parser *parser;
 39                                                    39 
 40         parser = devm_kzalloc(&motu->card->car     40         parser = devm_kzalloc(&motu->card->card_dev, sizeof(*parser), GFP_KERNEL);
 41         if (!parser)                               41         if (!parser)
 42                 return -ENOMEM;                    42                 return -ENOMEM;
 43         spin_lock_init(&parser->lock);             43         spin_lock_init(&parser->lock);
 44         motu->message_parser = parser;             44         motu->message_parser = parser;
 45                                                    45 
 46         return 0;                                  46         return 0;
 47 }                                                  47 }
 48                                                    48 
 49 int snd_motu_command_dsp_message_parser_init(s     49 int snd_motu_command_dsp_message_parser_init(struct snd_motu *motu, enum cip_sfc sfc)
 50 {                                                  50 {
 51         struct msg_parser *parser = motu->mess     51         struct msg_parser *parser = motu->message_parser;
 52                                                    52 
 53         parser->state = INITIALIZED;               53         parser->state = INITIALIZED;
 54                                                    54 
 55         // All of data blocks don't have messa     55         // All of data blocks don't have messages with meaningful information.
 56         switch (sfc) {                             56         switch (sfc) {
 57         case CIP_SFC_176400:                       57         case CIP_SFC_176400:
 58         case CIP_SFC_192000:                       58         case CIP_SFC_192000:
 59                 parser->interval = 4;              59                 parser->interval = 4;
 60                 break;                             60                 break;
 61         case CIP_SFC_88200:                        61         case CIP_SFC_88200:
 62         case CIP_SFC_96000:                        62         case CIP_SFC_96000:
 63                 parser->interval = 2;              63                 parser->interval = 2;
 64                 break;                             64                 break;
 65         case CIP_SFC_32000:                        65         case CIP_SFC_32000:
 66         case CIP_SFC_44100:                        66         case CIP_SFC_44100:
 67         case CIP_SFC_48000:                        67         case CIP_SFC_48000:
 68         default:                                   68         default:
 69                 parser->interval = 1;              69                 parser->interval = 1;
 70                 break;                             70                 break;
 71         }                                          71         }
 72                                                    72 
 73         return 0;                                  73         return 0;
 74 }                                                  74 }
 75                                                    75 
 76 #define FRAGMENT_POS                    6          76 #define FRAGMENT_POS                    6
 77 #define MIDI_BYTE_POS                   7          77 #define MIDI_BYTE_POS                   7
 78 #define MIDI_FLAG_POS                   8          78 #define MIDI_FLAG_POS                   8
 79 // One value of hardware meter consists of 4 m     79 // One value of hardware meter consists of 4 messages.
 80 #define FRAGMENTS_PER_VALUE             4          80 #define FRAGMENTS_PER_VALUE             4
 81 #define VALUES_AT_IMAGE_END             0xffff     81 #define VALUES_AT_IMAGE_END             0xffffffffffffffff
 82                                                    82 
 83 void snd_motu_command_dsp_message_parser_parse !!  83 void snd_motu_command_dsp_message_parser_parse(struct snd_motu *motu, const struct pkt_desc *descs,
 84                                         const  !!  84                                         unsigned int desc_count, unsigned int data_block_quadlets)
 85 {                                                  85 {
 86         struct snd_motu *motu = container_of(s << 
 87         unsigned int data_block_quadlets = s-> << 
 88         struct msg_parser *parser = motu->mess     86         struct msg_parser *parser = motu->message_parser;
 89         unsigned int interval = parser->interv     87         unsigned int interval = parser->interval;
 90         unsigned long flags;                       88         unsigned long flags;
 91         int i;                                     89         int i;
 92                                                    90 
 93         spin_lock_irqsave(&parser->lock, flags     91         spin_lock_irqsave(&parser->lock, flags);
 94                                                    92 
 95         for (i = 0; i < count; ++i) {          !!  93         for (i = 0; i < desc_count; ++i) {
                                                   >>  94                 const struct pkt_desc *desc = descs + i;
 96                 __be32 *buffer = desc->ctx_pay     95                 __be32 *buffer = desc->ctx_payload;
 97                 unsigned int data_blocks = des     96                 unsigned int data_blocks = desc->data_blocks;
 98                 int j;                             97                 int j;
 99                                                << 
100                 desc = amdtp_stream_next_packe << 
101                                                    98 
102                 for (j = 0; j < data_blocks; +     99                 for (j = 0; j < data_blocks; ++j) {
103                         u8 *b = (u8 *)buffer;     100                         u8 *b = (u8 *)buffer;
104                         buffer += data_block_q    101                         buffer += data_block_quadlets;
105                                                   102 
106                         switch (parser->state)    103                         switch (parser->state) {
107                         case INITIALIZED:         104                         case INITIALIZED:
108                         {                         105                         {
109                                 u8 fragment =     106                                 u8 fragment = b[FRAGMENT_POS];
110                                                   107 
111                                 if (fragment >    108                                 if (fragment > 0) {
112                                         parser    109                                         parser->value = fragment;
113                                         parser    110                                         parser->message_count = 1;
114                                         parser    111                                         parser->state = FRAGMENT_DETECTED;
115                                 }                 112                                 }
116                                 break;            113                                 break;
117                         }                         114                         }
118                         case FRAGMENT_DETECTED    115                         case FRAGMENT_DETECTED:
119                         {                         116                         {
120                                 if (parser->me    117                                 if (parser->message_count % interval == 0) {
121                                         u8 fra    118                                         u8 fragment = b[FRAGMENT_POS];
122                                                   119 
123                                         parser    120                                         parser->value >>= 8;
124                                         parser    121                                         parser->value |= (u64)fragment << 56;
125                                                   122 
126                                         if (pa    123                                         if (parser->value == VALUES_AT_IMAGE_END) {
127                                                   124                                                 parser->state = AVAILABLE;
128                                                   125                                                 parser->fragment_pos = 0;
129                                                   126                                                 parser->value_index = 0;
130                                                   127                                                 parser->message_count = 0;
131                                         }         128                                         }
132                                 }                 129                                 }
133                                 ++parser->mess    130                                 ++parser->message_count;
134                                 break;            131                                 break;
135                         }                         132                         }
136                         case AVAILABLE:           133                         case AVAILABLE:
137                         default:                  134                         default:
138                         {                         135                         {
139                                 if (parser->me    136                                 if (parser->message_count % interval == 0) {
140                                         u8 fra    137                                         u8 fragment = b[FRAGMENT_POS];
141                                                   138 
142                                         parser    139                                         parser->value >>= 8;
143                                         parser    140                                         parser->value |= (u64)fragment << 56;
144                                         ++pars    141                                         ++parser->fragment_pos;
145                                                   142 
146                                         if (pa    143                                         if (parser->fragment_pos == 4) {
147                                                   144                                                 // Skip the last two quadlets since they could be
148                                                   145                                                 // invalid value (0xffffffff) as floating point
149                                                   146                                                 // number.
150                                                   147                                                 if (parser->value_index <
151                                                   148                                                     SNDRV_FIREWIRE_MOTU_COMMAND_DSP_METER_COUNT - 2) {
152                                                   149                                                         u32 val = (u32)(parser->value >> 32);
153                                                   150                                                         parser->meter.data[parser->value_index] = val;
154                                                   151                                                 }
155                                                   152                                                 ++parser->value_index;
156                                                   153                                                 parser->fragment_pos = 0;
157                                         }         154                                         }
158                                                   155 
159                                         if (pa    156                                         if (parser->value == VALUES_AT_IMAGE_END) {
160                                                   157                                                 parser->value_index = 0;
161                                                   158                                                 parser->fragment_pos = 0;
162                                                   159                                                 parser->message_count = 0;
163                                         }         160                                         }
164                                 }                 161                                 }
165                                 ++parser->mess    162                                 ++parser->message_count;
166                                 break;            163                                 break;
167                         }                         164                         }
168                         }                         165                         }
169                 }                                 166                 }
170         }                                         167         }
171                                                   168 
172         spin_unlock_irqrestore(&parser->lock,     169         spin_unlock_irqrestore(&parser->lock, flags);
173 }                                                 170 }
174                                                   171 
175 void snd_motu_command_dsp_message_parser_copy_    172 void snd_motu_command_dsp_message_parser_copy_meter(struct snd_motu *motu,
176                                         struct    173                                         struct snd_firewire_motu_command_dsp_meter *meter)
177 {                                                 174 {
178         struct msg_parser *parser = motu->mess    175         struct msg_parser *parser = motu->message_parser;
179         unsigned long flags;                      176         unsigned long flags;
180                                                   177 
181         spin_lock_irqsave(&parser->lock, flags    178         spin_lock_irqsave(&parser->lock, flags);
182         memcpy(meter, &parser->meter, sizeof(*    179         memcpy(meter, &parser->meter, sizeof(*meter));
183         spin_unlock_irqrestore(&parser->lock,     180         spin_unlock_irqrestore(&parser->lock, flags);
184 }                                                 181 }
185                                                   182 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php