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

TOMOYO Linux Cross Reference
Linux/sound/firewire/motu/motu-register-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-register-dsp-message-parser.c (Version linux-6.12-rc7) and /sound/firewire/motu/motu-register-dsp-message-parser.c (Version linux-4.9.337)


  1 // SPDX-License-Identifier: GPL-2.0-only            1 
  2 //                                                
  3 // motu-register-dsp-message-parser.c - a part    
  4 //                                                
  5 // Copyright (c) 2021 Takashi Sakamoto <o-taka    
  6                                                   
  7 // Below models allow software to configure th    
  8 // to access their internal registers.            
  9 // * 828 mk2                                      
 10 // * 896hd                                        
 11 // * Traveler                                     
 12 // * 8 pre                                        
 13 // * Ultralite                                    
 14 // * 4 pre                                        
 15 // * Audio Express                                
 16 //                                                
 17 // Additionally, isochronous packets from the     
 18 // DSP. The messages are two set of 3 byte dat    
 19 // operates hardware components such as dial a    
 20 // The messages include Hardware metering and     
 21                                                   
 22 #include "motu.h"                                 
 23                                                   
 24 #define MSG_FLAG_POS                    4         
 25 #define MSG_FLAG_TYPE_MASK              0xf8      
 26 #define MSG_FLAG_MIDI_MASK              0x01      
 27 #define MSG_FLAG_MODEL_SPECIFIC_MASK    0x06      
 28 #define   MSG_FLAG_8PRE                 0x00      
 29 #define   MSG_FLAG_ULTRALITE            0x04      
 30 #define   MSG_FLAG_TRAVELER             0x04      
 31 #define   MSG_FLAG_828MK2               0x04      
 32 #define   MSG_FLAG_896HD                0x04      
 33 #define   MSG_FLAG_4PRE                 0x05 /    
 34 #define   MSG_FLAG_AUDIOEXPRESS         0x05 /    
 35 #define MSG_FLAG_TYPE_SHIFT             3         
 36 #define MSG_VALUE_POS                   5         
 37 #define MSG_MIDI_BYTE_POS               6         
 38 #define MSG_METER_IDX_POS               7         
 39                                                   
 40 // In 4 pre and Audio express, meter index is     
 41 // is in 7th byte.                                
 42 #define MSG_METER_IDX_POS_4PRE_AE       6         
 43 #define MSG_MIDI_BYTE_POS_4PRE_AE       7         
 44 #define MSG_FLAG_MIDI_POS_4PRE_AE       8         
 45                                                   
 46 enum register_dsp_msg_type {                      
 47         // Used for messages with no informati    
 48         INVALID = 0x00,                           
 49         MIXER_SELECT = 0x01,                      
 50         MIXER_SRC_GAIN = 0x02,                    
 51         MIXER_SRC_PAN = 0x03,                     
 52         MIXER_SRC_FLAG = 0x04,                    
 53         MIXER_OUTPUT_PAIRED_VOLUME = 0x05,        
 54         MIXER_OUTPUT_PAIRED_FLAG = 0x06,          
 55         MAIN_OUTPUT_PAIRED_VOLUME = 0x07,         
 56         HP_OUTPUT_PAIRED_VOLUME = 0x08,           
 57         HP_OUTPUT_PAIRED_ASSIGNMENT = 0x09,       
 58         // Transferred by all models but the p    
 59         UNKNOWN_0 = 0x0a,                         
 60         // Specific to 828mk2, 896hd, Traveler    
 61         UNKNOWN_2 = 0x0c,                         
 62         // Specific to 828mk2, Traveler, and 8    
 63         LINE_INPUT_BOOST = 0x0d,                  
 64         // Specific to 828mk2, Traveler, and 8    
 65         LINE_INPUT_NOMINAL_LEVEL = 0x0e,          
 66         // Specific to Ultralite, 4 pre, Audio    
 67         INPUT_GAIN_AND_INVERT = 0x15,             
 68         // Specific to 4 pre, and Audio expres    
 69         INPUT_FLAG = 0x16,                        
 70         // Specific to 4 pre, and Audio expres    
 71         MIXER_SRC_PAIRED_BALANCE = 0x17,          
 72         // Specific to 4 pre, and Audio expres    
 73         MIXER_SRC_PAIRED_WIDTH = 0x18,            
 74         // Transferred by all models. This typ    
 75         // messages. The message delivers sign    
 76         // Traveler, one of physical outputs i    
 77         // by LSB one byte in asynchronous wri    
 78         METER = 0x1f,                             
 79 };                                                
 80                                                   
 81 #define EVENT_QUEUE_SIZE        16                
 82                                                   
 83 struct msg_parser {                               
 84         spinlock_t lock;                          
 85         struct snd_firewire_motu_register_dsp_    
 86         bool meter_pos_quirk;                     
 87                                                   
 88         struct snd_firewire_motu_register_dsp_    
 89         u8 prev_mixer_src_type;                   
 90         u8 mixer_ch;                              
 91         u8 mixer_src_ch;                          
 92                                                   
 93         u8 input_ch;                              
 94         u8 prev_msg_type;                         
 95                                                   
 96         u32 event_queue[EVENT_QUEUE_SIZE];        
 97         unsigned int push_pos;                    
 98         unsigned int pull_pos;                    
 99 };                                                
100                                                   
101 int snd_motu_register_dsp_message_parser_new(s    
102 {                                                 
103         struct msg_parser *parser;                
104         parser = devm_kzalloc(&motu->card->car    
105         if (!parser)                              
106                 return -ENOMEM;                   
107         spin_lock_init(&parser->lock);            
108         if (motu->spec == &snd_motu_spec_4pre     
109                 parser->meter_pos_quirk = true    
110         motu->message_parser = parser;            
111         return 0;                                 
112 }                                                 
113                                                   
114 int snd_motu_register_dsp_message_parser_init(    
115 {                                                 
116         struct msg_parser *parser = motu->mess    
117                                                   
118         parser->prev_mixer_src_type = INVALID;    
119         parser->mixer_ch = 0xff;                  
120         parser->mixer_src_ch = 0xff;              
121         parser->prev_msg_type = INVALID;          
122                                                   
123         return 0;                                 
124 }                                                 
125                                                   
126 // Rough implementaion of queue without overru    
127 static void queue_event(struct snd_motu *motu,    
128 {                                                 
129         struct msg_parser *parser = motu->mess    
130         unsigned int pos = parser->push_pos;      
131         u32 entry;                                
132                                                   
133         if (!motu->hwdep || motu->hwdep->used     
134                 return;                           
135                                                   
136         entry = (msg_type << 24) | (identifier    
137         parser->event_queue[pos] = entry;         
138                                                   
139         ++pos;                                    
140         if (pos >= EVENT_QUEUE_SIZE)              
141                 pos = 0;                          
142         parser->push_pos = pos;                   
143 }                                                 
144                                                   
145 void snd_motu_register_dsp_message_parser_pars    
146                                                   
147 {                                                 
148         struct snd_motu *motu = container_of(s    
149         unsigned int data_block_quadlets = s->    
150         struct msg_parser *parser = motu->mess    
151         bool meter_pos_quirk = parser->meter_p    
152         unsigned int pos = parser->push_pos;      
153         unsigned long flags;                      
154         int i;                                    
155                                                   
156         spin_lock_irqsave(&parser->lock, flags    
157                                                   
158         for (i = 0; i < count; ++i) {             
159                 __be32 *buffer = desc->ctx_pay    
160                 unsigned int data_blocks = des    
161                 int j;                            
162                                                   
163                 desc = amdtp_stream_next_packe    
164                                                   
165                 for (j = 0; j < data_blocks; +    
166                         u8 *b = (u8 *)buffer;     
167                         u8 msg_type = (b[MSG_F    
168                         u8 val = b[MSG_VALUE_P    
169                                                   
170                         buffer += data_block_q    
171                                                   
172                         switch (msg_type) {       
173                         case MIXER_SELECT:        
174                         {                         
175                                 u8 mixer_ch =     
176                                 if (mixer_ch <    
177                                         parser    
178                                         parser    
179                                 }                 
180                                 break;            
181                         }                         
182                         case MIXER_SRC_GAIN:      
183                         case MIXER_SRC_PAN:       
184                         case MIXER_SRC_FLAG:      
185                         case MIXER_SRC_PAIRED_    
186                         case MIXER_SRC_PAIRED_    
187                         {                         
188                                 struct snd_fir    
189                                 u8 mixer_ch =     
190                                 u8 mixer_src_c    
191                                                   
192                                 if (msg_type !    
193                                         mixer_    
194                                 else              
195                                         ++mixe    
196                                 parser->prev_m    
197                                                   
198                                 if (mixer_ch <    
199                                     mixer_src_    
200                                         u8 mix    
201                                                   
202                                         switch    
203                                         case M    
204                                                   
205                                                   
206                                                   
207                                                   
208                                                   
209                                         case M    
210                                                   
211                                                   
212                                                   
213                                                   
214                                                   
215                                         case M    
216                                                   
217                                                   
218                                                   
219                                                   
220                                                   
221                                         case M    
222                                                   
223                                                   
224                                                   
225                                                   
226                                                   
227                                         case M    
228                                                   
229                                                   
230                                                   
231                                                   
232                                                   
233                                         defaul    
234                                                   
235                                         }         
236                                                   
237                                         parser    
238                                 }                 
239                                 break;            
240                         }                         
241                         case MIXER_OUTPUT_PAIR    
242                         case MIXER_OUTPUT_PAIR    
243                         {                         
244                                 struct snd_fir    
245                                 u8 mixer_ch =     
246                                                   
247                                 if (mixer_ch <    
248                                         switch    
249                                         case M    
250                                                   
251                                                   
252                                                   
253                                                   
254                                                   
255                                         case M    
256                                                   
257                                                   
258                                                   
259                                                   
260                                                   
261                                         defaul    
262                                                   
263                                         }         
264                                 }                 
265                                 break;            
266                         }                         
267                         case MAIN_OUTPUT_PAIRE    
268                                 if (parser->pa    
269                                         queue_    
270                                         parser    
271                                 }                 
272                                 break;            
273                         case HP_OUTPUT_PAIRED_    
274                                 if (parser->pa    
275                                         queue_    
276                                         parser    
277                                 }                 
278                                 break;            
279                         case HP_OUTPUT_PAIRED_    
280                                 if (parser->pa    
281                                         queue_    
282                                         parser    
283                                 }                 
284                                 break;            
285                         case LINE_INPUT_BOOST:    
286                                 if (parser->pa    
287                                         queue_    
288                                         parser    
289                                 }                 
290                                 break;            
291                         case LINE_INPUT_NOMINA    
292                                 if (parser->pa    
293                                         queue_    
294                                         parser    
295                                 }                 
296                                 break;            
297                         case INPUT_GAIN_AND_IN    
298                         case INPUT_FLAG:          
299                         {                         
300                                 struct snd_fir    
301                                 u8 input_ch =     
302                                                   
303                                 if (parser->pr    
304                                         input_    
305                                 else              
306                                         ++inpu    
307                                                   
308                                 if (input_ch <    
309                                         switch    
310                                         case I    
311                                                   
312                                                   
313                                                   
314                                                   
315                                                   
316                                         case I    
317                                                   
318                                                   
319                                                   
320                                                   
321                                                   
322                                         defaul    
323                                                   
324                                         }         
325                                         parser    
326                                 }                 
327                                 break;            
328                         }                         
329                         case UNKNOWN_0:           
330                         case UNKNOWN_2:           
331                                 break;            
332                         case METER:               
333                         {                         
334                                 u8 pos;           
335                                                   
336                                 if (!meter_pos    
337                                         pos =     
338                                 else              
339                                         pos =     
340                                                   
341                                 if (pos < SNDR    
342                                         parser    
343                                 } else if (pos    
344                                         pos -=    
345                                                   
346                                         if (po    
347                                                   
348                                 }                 
349                                                   
350                                 // The message    
351                                 // types of me    
352                                 fallthrough;      
353                         }                         
354                         case INVALID:             
355                         default:                  
356                                 // Don't cache    
357                                 continue;         
358                         }                         
359                                                   
360                         parser->prev_msg_type     
361                 }                                 
362         }                                         
363                                                   
364         if (pos != parser->push_pos)              
365                 wake_up(&motu->hwdep_wait);       
366                                                   
367         spin_unlock_irqrestore(&parser->lock,     
368 }                                                 
369                                                   
370 void snd_motu_register_dsp_message_parser_copy    
371                                                   
372 {                                                 
373         struct msg_parser *parser = motu->mess    
374         unsigned long flags;                      
375                                                   
376         spin_lock_irqsave(&parser->lock, flags    
377         memcpy(meter, &parser->meter, sizeof(*    
378         spin_unlock_irqrestore(&parser->lock,     
379 }                                                 
380                                                   
381 void snd_motu_register_dsp_message_parser_copy    
382                                         struct    
383 {                                                 
384         struct msg_parser *parser = motu->mess    
385         unsigned long flags;                      
386                                                   
387         spin_lock_irqsave(&parser->lock, flags    
388         memcpy(param, &parser->param, sizeof(*    
389         spin_unlock_irqrestore(&parser->lock,     
390 }                                                 
391                                                   
392 unsigned int snd_motu_register_dsp_message_par    
393 {                                                 
394         struct msg_parser *parser = motu->mess    
395                                                   
396         if (parser->pull_pos > parser->push_po    
397                 return EVENT_QUEUE_SIZE - pars    
398         else                                      
399                 return parser->push_pos - pars    
400 }                                                 
401                                                   
402 bool snd_motu_register_dsp_message_parser_copy    
403 {                                                 
404         struct msg_parser *parser = motu->mess    
405         unsigned int pos = parser->pull_pos;      
406         unsigned long flags;                      
407                                                   
408         if (pos == parser->push_pos)              
409                 return false;                     
410                                                   
411         spin_lock_irqsave(&parser->lock, flags    
412                                                   
413         *event = parser->event_queue[pos];        
414                                                   
415         ++pos;                                    
416         if (pos >= EVENT_QUEUE_SIZE)              
417                 pos = 0;                          
418         parser->pull_pos = pos;                   
419                                                   
420         spin_unlock_irqrestore(&parser->lock,     
421                                                   
422         return true;                              
423 }                                                 
424                                                   

~ [ 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