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

TOMOYO Linux Cross Reference
Linux/sound/firewire/bebob/bebob_stream.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ 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.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 /*
  3  * bebob_stream.c - a part of driver for BeBoB based devices
  4  *
  5  * Copyright (c) 2013-2014 Takashi Sakamoto
  6  */
  7 
  8 #include "./bebob.h"
  9 
 10 #define READY_TIMEOUT_MS        4000
 11 
 12 /*
 13  * NOTE;
 14  * For BeBoB streams, Both of input and output CMP connection are important.
 15  *
 16  * For most devices, each CMP connection starts to transmit/receive a
 17  * corresponding stream. But for a few devices, both of CMP connection needs
 18  * to start transmitting stream. An example is 'M-Audio Firewire 410'.
 19  */
 20 
 21 /* 128 is an arbitrary length but it seems to be enough */
 22 #define FORMAT_MAXIMUM_LENGTH 128
 23 
 24 const unsigned int snd_bebob_rate_table[SND_BEBOB_STRM_FMT_ENTRIES] = {
 25         [0] = 32000,
 26         [1] = 44100,
 27         [2] = 48000,
 28         [3] = 88200,
 29         [4] = 96000,
 30         [5] = 176400,
 31         [6] = 192000,
 32 };
 33 
 34 /*
 35  * See: Table 51: Extended Stream Format Info ‘Sampling Frequency’
 36  * in Additional AVC commands (Nov 2003, BridgeCo)
 37  */
 38 static const unsigned int bridgeco_freq_table[] = {
 39         [0] = 0x02,
 40         [1] = 0x03,
 41         [2] = 0x04,
 42         [3] = 0x0a,
 43         [4] = 0x05,
 44         [5] = 0x06,
 45         [6] = 0x07,
 46 };
 47 
 48 static int
 49 get_formation_index(unsigned int rate, unsigned int *index)
 50 {
 51         unsigned int i;
 52 
 53         for (i = 0; i < ARRAY_SIZE(snd_bebob_rate_table); i++) {
 54                 if (snd_bebob_rate_table[i] == rate) {
 55                         *index = i;
 56                         return 0;
 57                 }
 58         }
 59         return -EINVAL;
 60 }
 61 
 62 int
 63 snd_bebob_stream_get_rate(struct snd_bebob *bebob, unsigned int *curr_rate)
 64 {
 65         unsigned int tx_rate, rx_rate, trials;
 66         int err;
 67 
 68         trials = 0;
 69         do {
 70                 err = avc_general_get_sig_fmt(bebob->unit, &tx_rate,
 71                                               AVC_GENERAL_PLUG_DIR_OUT, 0);
 72         } while (err == -EAGAIN && ++trials < 3);
 73         if (err < 0)
 74                 goto end;
 75 
 76         trials = 0;
 77         do {
 78                 err = avc_general_get_sig_fmt(bebob->unit, &rx_rate,
 79                                               AVC_GENERAL_PLUG_DIR_IN, 0);
 80         } while (err == -EAGAIN && ++trials < 3);
 81         if (err < 0)
 82                 goto end;
 83 
 84         *curr_rate = rx_rate;
 85         if (rx_rate == tx_rate)
 86                 goto end;
 87 
 88         /* synchronize receive stream rate to transmit stream rate */
 89         err = avc_general_set_sig_fmt(bebob->unit, rx_rate,
 90                                       AVC_GENERAL_PLUG_DIR_IN, 0);
 91 end:
 92         return err;
 93 }
 94 
 95 int
 96 snd_bebob_stream_set_rate(struct snd_bebob *bebob, unsigned int rate)
 97 {
 98         int err;
 99 
100         err = avc_general_set_sig_fmt(bebob->unit, rate,
101                                       AVC_GENERAL_PLUG_DIR_OUT, 0);
102         if (err < 0)
103                 goto end;
104 
105         err = avc_general_set_sig_fmt(bebob->unit, rate,
106                                       AVC_GENERAL_PLUG_DIR_IN, 0);
107         if (err < 0)
108                 goto end;
109 
110         /*
111          * Some devices need a bit time for transition.
112          * 300msec is got by some experiments.
113          */
114         msleep(300);
115 end:
116         return err;
117 }
118 
119 int snd_bebob_stream_get_clock_src(struct snd_bebob *bebob,
120                                    enum snd_bebob_clock_type *src)
121 {
122         const struct snd_bebob_clock_spec *clk_spec = bebob->spec->clock;
123         u8 addr[AVC_BRIDGECO_ADDR_BYTES], input[7];
124         unsigned int id;
125         enum avc_bridgeco_plug_type type;
126         int err = 0;
127 
128         /* 1.The device has its own operation to switch source of clock */
129         if (clk_spec) {
130                 err = clk_spec->get(bebob, &id);
131                 if (err < 0) {
132                         dev_err(&bebob->unit->device,
133                                 "fail to get clock source: %d\n", err);
134                         goto end;
135                 }
136 
137                 if (id >= clk_spec->num) {
138                         dev_err(&bebob->unit->device,
139                                 "clock source %d out of range 0..%d\n",
140                                 id, clk_spec->num - 1);
141                         err = -EIO;
142                         goto end;
143                 }
144 
145                 *src = clk_spec->types[id];
146                 goto end;
147         }
148 
149         /*
150          * 2.The device don't support to switch source of clock then assumed
151          *   to use internal clock always
152          */
153         if (bebob->sync_input_plug < 0) {
154                 *src = SND_BEBOB_CLOCK_TYPE_INTERNAL;
155                 goto end;
156         }
157 
158         /*
159          * 3.The device supports to switch source of clock by an usual way.
160          *   Let's check input for 'Music Sub Unit Sync Input' plug.
161          */
162         avc_bridgeco_fill_msu_addr(addr, AVC_BRIDGECO_PLUG_DIR_IN,
163                                    bebob->sync_input_plug);
164         err = avc_bridgeco_get_plug_input(bebob->unit, addr, input);
165         if (err < 0) {
166                 dev_err(&bebob->unit->device,
167                         "fail to get an input for MSU in plug %d: %d\n",
168                         bebob->sync_input_plug, err);
169                 goto end;
170         }
171 
172         /*
173          * If there are no input plugs, all of fields are 0xff.
174          * Here check the first field. This field is used for direction.
175          */
176         if (input[0] == 0xff) {
177                 *src = SND_BEBOB_CLOCK_TYPE_INTERNAL;
178                 goto end;
179         }
180 
181         /* The source from any output plugs is for one purpose only. */
182         if (input[0] == AVC_BRIDGECO_PLUG_DIR_OUT) {
183                 /*
184                  * In BeBoB architecture, the source from music subunit may
185                  * bypass from oPCR[0]. This means that this source gives
186                  * synchronization to IEEE 1394 cycle start packet.
187                  */
188                 if (input[1] == AVC_BRIDGECO_PLUG_MODE_SUBUNIT &&
189                     input[2] == 0x0c) {
190                         *src = SND_BEBOB_CLOCK_TYPE_INTERNAL;
191                         goto end;
192                 }
193         /* The source from any input units is for several purposes. */
194         } else if (input[1] == AVC_BRIDGECO_PLUG_MODE_UNIT) {
195                 if (input[2] == AVC_BRIDGECO_PLUG_UNIT_ISOC) {
196                         if (input[3] == 0x00) {
197                                 /*
198                                  * This source comes from iPCR[0]. This means
199                                  * that presentation timestamp calculated by
200                                  * SYT series of the received packets. In
201                                  * short, this driver is the master of
202                                  * synchronization.
203                                  */
204                                 *src = SND_BEBOB_CLOCK_TYPE_SYT;
205                                 goto end;
206                         } else {
207                                 /*
208                                  * This source comes from iPCR[1-29]. This
209                                  * means that the synchronization stream is not
210                                  * the Audio/MIDI compound stream.
211                                  */
212                                 *src = SND_BEBOB_CLOCK_TYPE_EXTERNAL;
213                                 goto end;
214                         }
215                 } else if (input[2] == AVC_BRIDGECO_PLUG_UNIT_EXT) {
216                         /* Check type of this plug.  */
217                         avc_bridgeco_fill_unit_addr(addr,
218                                                     AVC_BRIDGECO_PLUG_DIR_IN,
219                                                     AVC_BRIDGECO_PLUG_UNIT_EXT,
220                                                     input[3]);
221                         err = avc_bridgeco_get_plug_type(bebob->unit, addr,
222                                                          &type);
223                         if (err < 0)
224                                 goto end;
225 
226                         if (type == AVC_BRIDGECO_PLUG_TYPE_DIG) {
227                                 /*
228                                  * SPDIF/ADAT or sometimes (not always) word
229                                  * clock.
230                                  */
231                                 *src = SND_BEBOB_CLOCK_TYPE_EXTERNAL;
232                                 goto end;
233                         } else if (type == AVC_BRIDGECO_PLUG_TYPE_SYNC) {
234                                 /* Often word clock. */
235                                 *src = SND_BEBOB_CLOCK_TYPE_EXTERNAL;
236                                 goto end;
237                         } else if (type == AVC_BRIDGECO_PLUG_TYPE_ADDITION) {
238                                 /*
239                                  * Not standard.
240                                  * Mostly, additional internal clock.
241                                  */
242                                 *src = SND_BEBOB_CLOCK_TYPE_INTERNAL;
243                                 goto end;
244                         }
245                 }
246         }
247 
248         /* Not supported. */
249         err = -EIO;
250 end:
251         return err;
252 }
253 
254 static int map_data_channels(struct snd_bebob *bebob, struct amdtp_stream *s)
255 {
256         unsigned int sec, sections, ch, channels;
257         unsigned int pcm, midi, location;
258         unsigned int stm_pos, sec_loc, pos;
259         u8 *buf, addr[AVC_BRIDGECO_ADDR_BYTES], type;
260         enum avc_bridgeco_plug_dir dir;
261         int err;
262 
263         /*
264          * The length of return value of this command cannot be expected. Here
265          * use the maximum length of FCP.
266          */
267         buf = kzalloc(256, GFP_KERNEL);
268         if (buf == NULL)
269                 return -ENOMEM;
270 
271         if (s == &bebob->tx_stream)
272                 dir = AVC_BRIDGECO_PLUG_DIR_OUT;
273         else
274                 dir = AVC_BRIDGECO_PLUG_DIR_IN;
275 
276         avc_bridgeco_fill_unit_addr(addr, dir, AVC_BRIDGECO_PLUG_UNIT_ISOC, 0);
277         err = avc_bridgeco_get_plug_ch_pos(bebob->unit, addr, buf, 256);
278         if (err < 0) {
279                 dev_err(&bebob->unit->device,
280                         "fail to get channel position for isoc %s plug 0: %d\n",
281                         (dir == AVC_BRIDGECO_PLUG_DIR_IN) ? "in" : "out",
282                         err);
283                 goto end;
284         }
285         pos = 0;
286 
287         /* positions in I/O buffer */
288         pcm = 0;
289         midi = 0;
290 
291         /* the number of sections in AMDTP packet */
292         sections = buf[pos++];
293 
294         for (sec = 0; sec < sections; sec++) {
295                 /* type of this section */
296                 avc_bridgeco_fill_unit_addr(addr, dir,
297                                             AVC_BRIDGECO_PLUG_UNIT_ISOC, 0);
298                 err = avc_bridgeco_get_plug_section_type(bebob->unit, addr,
299                                                          sec, &type);
300                 if (err < 0) {
301                         dev_err(&bebob->unit->device,
302                         "fail to get section type for isoc %s plug 0: %d\n",
303                                 (dir == AVC_BRIDGECO_PLUG_DIR_IN) ? "in" :
304                                                                     "out",
305                                 err);
306                         goto end;
307                 }
308                 /* NoType */
309                 if (type == 0xff) {
310                         err = -ENOSYS;
311                         goto end;
312                 }
313 
314                 /* the number of channels in this section */
315                 channels = buf[pos++];
316 
317                 for (ch = 0; ch < channels; ch++) {
318                         /* position of this channel in AMDTP packet */
319                         stm_pos = buf[pos++] - 1;
320                         /* location of this channel in this section */
321                         sec_loc = buf[pos++] - 1;
322 
323                         /*
324                          * Basically the number of location is within the
325                          * number of channels in this section. But some models
326                          * of M-Audio don't follow this. Its location for MIDI
327                          * is the position of MIDI channels in AMDTP packet.
328                          */
329                         if (sec_loc >= channels)
330                                 sec_loc = ch;
331 
332                         switch (type) {
333                         /* for MIDI conformant data channel */
334                         case 0x0a:
335                                 /* AMDTP_MAX_CHANNELS_FOR_MIDI is 1. */
336                                 if ((midi > 0) && (stm_pos != midi)) {
337                                         err = -ENOSYS;
338                                         goto end;
339                                 }
340                                 amdtp_am824_set_midi_position(s, stm_pos);
341                                 midi = stm_pos;
342                                 break;
343                         /* for PCM data channel */
344                         case 0x01:      /* Headphone */
345                         case 0x02:      /* Microphone */
346                         case 0x03:      /* Line */
347                         case 0x04:      /* SPDIF */
348                         case 0x05:      /* ADAT */
349                         case 0x06:      /* TDIF */
350                         case 0x07:      /* MADI */
351                         /* for undefined/changeable signal  */
352                         case 0x08:      /* Analog */
353                         case 0x09:      /* Digital */
354                         default:
355                                 location = pcm + sec_loc;
356                                 if (location >= AM824_MAX_CHANNELS_FOR_PCM) {
357                                         err = -ENOSYS;
358                                         goto end;
359                                 }
360                                 amdtp_am824_set_pcm_position(s, location,
361                                                              stm_pos);
362                                 break;
363                         }
364                 }
365 
366                 if (type != 0x0a)
367                         pcm += channels;
368                 else
369                         midi += channels;
370         }
371 end:
372         kfree(buf);
373         return err;
374 }
375 
376 static int
377 check_connection_used_by_others(struct snd_bebob *bebob, struct amdtp_stream *s)
378 {
379         struct cmp_connection *conn;
380         bool used;
381         int err;
382 
383         if (s == &bebob->tx_stream)
384                 conn = &bebob->out_conn;
385         else
386                 conn = &bebob->in_conn;
387 
388         err = cmp_connection_check_used(conn, &used);
389         if ((err >= 0) && used && !amdtp_stream_running(s)) {
390                 dev_err(&bebob->unit->device,
391                         "Connection established by others: %cPCR[%d]\n",
392                         (conn->direction == CMP_OUTPUT) ? 'o' : 'i',
393                         conn->pcr_index);
394                 err = -EBUSY;
395         }
396 
397         return err;
398 }
399 
400 static void break_both_connections(struct snd_bebob *bebob)
401 {
402         cmp_connection_break(&bebob->in_conn);
403         cmp_connection_break(&bebob->out_conn);
404 }
405 
406 static int start_stream(struct snd_bebob *bebob, struct amdtp_stream *stream)
407 {
408         struct cmp_connection *conn;
409         int err = 0;
410 
411         if (stream == &bebob->rx_stream)
412                 conn = &bebob->in_conn;
413         else
414                 conn = &bebob->out_conn;
415 
416         // channel mapping.
417         if (bebob->maudio_special_quirk == NULL) {
418                 err = map_data_channels(bebob, stream);
419                 if (err < 0)
420                         return err;
421         }
422 
423         err = cmp_connection_establish(conn);
424         if (err < 0)
425                 return err;
426 
427         return amdtp_domain_add_stream(&bebob->domain, stream,
428                                        conn->resources.channel, conn->speed);
429 }
430 
431 static int init_stream(struct snd_bebob *bebob, struct amdtp_stream *stream)
432 {
433         unsigned int flags = CIP_BLOCKING;
434         enum amdtp_stream_direction dir_stream;
435         struct cmp_connection *conn;
436         enum cmp_direction dir_conn;
437         int err;
438 
439         if (stream == &bebob->tx_stream) {
440                 dir_stream = AMDTP_IN_STREAM;
441                 conn = &bebob->out_conn;
442                 dir_conn = CMP_OUTPUT;
443         } else {
444                 dir_stream = AMDTP_OUT_STREAM;
445                 conn = &bebob->in_conn;
446                 dir_conn = CMP_INPUT;
447         }
448 
449         if (stream == &bebob->tx_stream) {
450                 if (bebob->quirks & SND_BEBOB_QUIRK_WRONG_DBC)
451                         flags |= CIP_EMPTY_HAS_WRONG_DBC;
452         }
453 
454         err = cmp_connection_init(conn, bebob->unit, dir_conn, 0);
455         if (err < 0)
456                 return err;
457 
458         err = amdtp_am824_init(stream, bebob->unit, dir_stream, flags);
459         if (err < 0) {
460                 cmp_connection_destroy(conn);
461                 return err;
462         }
463 
464         return 0;
465 }
466 
467 static void destroy_stream(struct snd_bebob *bebob, struct amdtp_stream *stream)
468 {
469         amdtp_stream_destroy(stream);
470 
471         if (stream == &bebob->tx_stream)
472                 cmp_connection_destroy(&bebob->out_conn);
473         else
474                 cmp_connection_destroy(&bebob->in_conn);
475 }
476 
477 int snd_bebob_stream_init_duplex(struct snd_bebob *bebob)
478 {
479         int err;
480 
481         err = init_stream(bebob, &bebob->tx_stream);
482         if (err < 0)
483                 return err;
484 
485         err = init_stream(bebob, &bebob->rx_stream);
486         if (err < 0) {
487                 destroy_stream(bebob, &bebob->tx_stream);
488                 return err;
489         }
490 
491         err = amdtp_domain_init(&bebob->domain);
492         if (err < 0) {
493                 destroy_stream(bebob, &bebob->tx_stream);
494                 destroy_stream(bebob, &bebob->rx_stream);
495         }
496 
497         return err;
498 }
499 
500 static int keep_resources(struct snd_bebob *bebob, struct amdtp_stream *stream,
501                           unsigned int rate, unsigned int index)
502 {
503         unsigned int pcm_channels;
504         unsigned int midi_ports;
505         struct cmp_connection *conn;
506         int err;
507 
508         if (stream == &bebob->tx_stream) {
509                 pcm_channels = bebob->tx_stream_formations[index].pcm;
510                 midi_ports = bebob->midi_input_ports;
511                 conn = &bebob->out_conn;
512         } else {
513                 pcm_channels = bebob->rx_stream_formations[index].pcm;
514                 midi_ports = bebob->midi_output_ports;
515                 conn = &bebob->in_conn;
516         }
517 
518         err = amdtp_am824_set_parameters(stream, rate, pcm_channels, midi_ports, false);
519         if (err < 0)
520                 return err;
521 
522         return cmp_connection_reserve(conn, amdtp_stream_get_max_payload(stream));
523 }
524 
525 int snd_bebob_stream_reserve_duplex(struct snd_bebob *bebob, unsigned int rate,
526                                     unsigned int frames_per_period,
527                                     unsigned int frames_per_buffer)
528 {
529         unsigned int curr_rate;
530         int err;
531 
532         // Considering JACK/FFADO streaming:
533         // TODO: This can be removed hwdep functionality becomes popular.
534         err = check_connection_used_by_others(bebob, &bebob->rx_stream);
535         if (err < 0)
536                 return err;
537 
538         err = bebob->spec->rate->get(bebob, &curr_rate);
539         if (err < 0)
540                 return err;
541         if (rate == 0)
542                 rate = curr_rate;
543         if (curr_rate != rate) {
544                 amdtp_domain_stop(&bebob->domain);
545                 break_both_connections(bebob);
546 
547                 cmp_connection_release(&bebob->out_conn);
548                 cmp_connection_release(&bebob->in_conn);
549         }
550 
551         if (bebob->substreams_counter == 0 || curr_rate != rate) {
552                 unsigned int index;
553 
554                 // NOTE:
555                 // If establishing connections at first, Yamaha GO46
556                 // (and maybe Terratec X24) don't generate sound.
557                 //
558                 // For firmware customized by M-Audio, refer to next NOTE.
559                 err = bebob->spec->rate->set(bebob, rate);
560                 if (err < 0) {
561                         dev_err(&bebob->unit->device,
562                                 "fail to set sampling rate: %d\n",
563                                 err);
564                         return err;
565                 }
566 
567                 err = get_formation_index(rate, &index);
568                 if (err < 0)
569                         return err;
570 
571                 err = keep_resources(bebob, &bebob->tx_stream, rate, index);
572                 if (err < 0)
573                         return err;
574 
575                 err = keep_resources(bebob, &bebob->rx_stream, rate, index);
576                 if (err < 0) {
577                         cmp_connection_release(&bebob->out_conn);
578                         return err;
579                 }
580 
581                 err = amdtp_domain_set_events_per_period(&bebob->domain,
582                                         frames_per_period, frames_per_buffer);
583                 if (err < 0) {
584                         cmp_connection_release(&bebob->out_conn);
585                         cmp_connection_release(&bebob->in_conn);
586                         return err;
587                 }
588         }
589 
590         return 0;
591 }
592 
593 int snd_bebob_stream_start_duplex(struct snd_bebob *bebob)
594 {
595         int err;
596 
597         // Need no substreams.
598         if (bebob->substreams_counter == 0)
599                 return -EIO;
600 
601         // packet queueing error or detecting discontinuity
602         if (amdtp_streaming_error(&bebob->rx_stream) ||
603             amdtp_streaming_error(&bebob->tx_stream)) {
604                 amdtp_domain_stop(&bebob->domain);
605                 break_both_connections(bebob);
606         }
607 
608         if (!amdtp_stream_running(&bebob->rx_stream)) {
609                 enum snd_bebob_clock_type src;
610                 unsigned int curr_rate;
611                 unsigned int tx_init_skip_cycles;
612 
613                 if (bebob->maudio_special_quirk) {
614                         err = bebob->spec->rate->get(bebob, &curr_rate);
615                         if (err < 0)
616                                 return err;
617                 }
618 
619                 err = snd_bebob_stream_get_clock_src(bebob, &src);
620                 if (err < 0)
621                         return err;
622 
623                 err = start_stream(bebob, &bebob->rx_stream);
624                 if (err < 0)
625                         goto error;
626 
627                 err = start_stream(bebob, &bebob->tx_stream);
628                 if (err < 0)
629                         goto error;
630 
631                 if (!(bebob->quirks & SND_BEBOB_QUIRK_INITIAL_DISCONTINUOUS_DBC))
632                         tx_init_skip_cycles = 0;
633                 else
634                         tx_init_skip_cycles = 16000;
635 
636                 // MEMO: Some devices start packet transmission long enough after establishment of
637                 // CMP connection. In the early stage of packet streaming, any device transfers
638                 // NODATA packets. After several hundred cycles, it begins to multiplex event into
639                 // the packet with adequate value of syt field in CIP header. Some devices are
640                 // strictly to generate any discontinuity in the sequence of tx packet when they
641                 // receives inadequate sequence of value in syt field of CIP header. In the case,
642                 // the request to break CMP connection is often corrupted, then any transaction
643                 // results in unrecoverable error, sometimes generate bus-reset.
644                 err = amdtp_domain_start(&bebob->domain, tx_init_skip_cycles, true, false);
645                 if (err < 0)
646                         goto error;
647 
648                 // NOTE:
649                 // The firmware customized by M-Audio uses these commands to
650                 // start transmitting stream. This is not usual way.
651                 if (bebob->maudio_special_quirk) {
652                         err = bebob->spec->rate->set(bebob, curr_rate);
653                         if (err < 0) {
654                                 dev_err(&bebob->unit->device,
655                                         "fail to ensure sampling rate: %d\n",
656                                         err);
657                                 goto error;
658                         }
659                 }
660 
661                 // Some devices postpone start of transmission mostly for 1 sec after receives
662                 // packets firstly.
663                 if (!amdtp_domain_wait_ready(&bebob->domain, READY_TIMEOUT_MS)) {
664                         err = -ETIMEDOUT;
665                         goto error;
666                 }
667         }
668 
669         return 0;
670 error:
671         amdtp_domain_stop(&bebob->domain);
672         break_both_connections(bebob);
673         return err;
674 }
675 
676 void snd_bebob_stream_stop_duplex(struct snd_bebob *bebob)
677 {
678         if (bebob->substreams_counter == 0) {
679                 amdtp_domain_stop(&bebob->domain);
680                 break_both_connections(bebob);
681 
682                 cmp_connection_release(&bebob->out_conn);
683                 cmp_connection_release(&bebob->in_conn);
684         }
685 }
686 
687 /*
688  * This function should be called before starting streams or after stopping
689  * streams.
690  */
691 void snd_bebob_stream_destroy_duplex(struct snd_bebob *bebob)
692 {
693         amdtp_domain_destroy(&bebob->domain);
694 
695         destroy_stream(bebob, &bebob->tx_stream);
696         destroy_stream(bebob, &bebob->rx_stream);
697 }
698 
699 /*
700  * See: Table 50: Extended Stream Format Info Format Hierarchy Level 2’
701  * in Additional AVC commands (Nov 2003, BridgeCo)
702  * Also 'Clause 12 AM824 sequence adaption layers' in IEC 61883-6:2005
703  */
704 static int
705 parse_stream_formation(u8 *buf, unsigned int len,
706                        struct snd_bebob_stream_formation *formation)
707 {
708         unsigned int i, e, channels, format;
709 
710         /*
711          * this module can support a hierarchy combination that:
712          *  Root:       Audio and Music (0x90)
713          *  Level 1:    AM824 Compound  (0x40)
714          */
715         if ((buf[0] != 0x90) || (buf[1] != 0x40))
716                 return -ENOSYS;
717 
718         /* check sampling rate */
719         for (i = 0; i < ARRAY_SIZE(bridgeco_freq_table); i++) {
720                 if (buf[2] == bridgeco_freq_table[i])
721                         break;
722         }
723         if (i == ARRAY_SIZE(bridgeco_freq_table))
724                 return -ENOSYS;
725 
726         /* Avoid double count by different entries for the same rate. */
727         memset(&formation[i], 0, sizeof(struct snd_bebob_stream_formation));
728 
729         for (e = 0; e < buf[4]; e++) {
730                 channels = buf[5 + e * 2];
731                 format = buf[6 + e * 2];
732 
733                 switch (format) {
734                 /* IEC 60958 Conformant, currently handled as MBLA */
735                 case 0x00:
736                 /* Multi bit linear audio */
737                 case 0x06:      /* Raw */
738                         formation[i].pcm += channels;
739                         break;
740                 /* MIDI Conformant */
741                 case 0x0d:
742                         formation[i].midi += channels;
743                         break;
744                 /* IEC 61937-3 to 7 */
745                 case 0x01:
746                 case 0x02:
747                 case 0x03:
748                 case 0x04:
749                 case 0x05:
750                 /* Multi bit linear audio */
751                 case 0x07:      /* DVD-Audio */
752                 case 0x0c:      /* High Precision */
753                 /* One Bit Audio */
754                 case 0x08:      /* (Plain) Raw */
755                 case 0x09:      /* (Plain) SACD */
756                 case 0x0a:      /* (Encoded) Raw */
757                 case 0x0b:      /* (Encoded) SACD */
758                 /* Synchronization Stream (Stereo Raw audio) */
759                 case 0x40:
760                 /* Don't care */
761                 case 0xff:
762                 default:
763                         return -ENOSYS; /* not supported */
764                 }
765         }
766 
767         if (formation[i].pcm  > AM824_MAX_CHANNELS_FOR_PCM ||
768             formation[i].midi > AM824_MAX_CHANNELS_FOR_MIDI)
769                 return -ENOSYS;
770 
771         return 0;
772 }
773 
774 static int fill_stream_formations(struct snd_bebob *bebob, u8 addr[AVC_BRIDGECO_ADDR_BYTES],
775                                   enum avc_bridgeco_plug_dir plug_dir, unsigned int plug_id,
776                                   struct snd_bebob_stream_formation *formations)
777 {
778         enum avc_bridgeco_plug_type plug_type;
779         u8 *buf;
780         unsigned int len, eid;
781         int err;
782 
783         avc_bridgeco_fill_unit_addr(addr, plug_dir, AVC_BRIDGECO_PLUG_UNIT_ISOC, plug_id);
784 
785         err = avc_bridgeco_get_plug_type(bebob->unit, addr, &plug_type);
786         if (err < 0) {
787                 dev_err(&bebob->unit->device,
788                         "Fail to get type for isoc %d plug 0: %d\n", plug_dir, err);
789                 return err;
790         } else if (plug_type != AVC_BRIDGECO_PLUG_TYPE_ISOC)
791                 return -ENXIO;
792 
793         buf = kmalloc(FORMAT_MAXIMUM_LENGTH, GFP_KERNEL);
794         if (buf == NULL)
795                 return -ENOMEM;
796 
797         for (eid = 0; eid < SND_BEBOB_STRM_FMT_ENTRIES; ++eid) {
798                 avc_bridgeco_fill_unit_addr(addr, plug_dir, AVC_BRIDGECO_PLUG_UNIT_ISOC, plug_id);
799 
800                 len = FORMAT_MAXIMUM_LENGTH;
801                 err = avc_bridgeco_get_plug_strm_fmt(bebob->unit, addr, buf, &len, eid);
802                 // No entries remained.
803                 if (err == -EINVAL && eid > 0) {
804                         err = 0;
805                         break;
806                 } else if (err < 0) {
807                         dev_err(&bebob->unit->device,
808                                 "fail to get stream format %d for isoc %d plug %d:%d\n",
809                                 eid, plug_dir, plug_id, err);
810                         break;
811                 }
812 
813                 err = parse_stream_formation(buf, len, formations);
814                 if (err < 0)
815                         break;
816         }
817 
818         kfree(buf);
819         return err;
820 }
821 
822 static int detect_midi_ports(struct snd_bebob *bebob,
823                              const struct snd_bebob_stream_formation *formats,
824                              u8 addr[AVC_BRIDGECO_ADDR_BYTES], enum avc_bridgeco_plug_dir plug_dir,
825                              unsigned int plug_count, unsigned int *midi_ports)
826 {
827         int i;
828         int err = 0;
829 
830         *midi_ports = 0;
831 
832         /// Detect the number of available MIDI ports when packet has MIDI conformant data channel.
833         for (i = 0; i < SND_BEBOB_STRM_FMT_ENTRIES; ++i) {
834                 if (formats[i].midi > 0)
835                         break;
836         }
837         if (i >= SND_BEBOB_STRM_FMT_ENTRIES)
838                 return 0;
839 
840         for (i = 0; i < plug_count; ++i) {
841                 enum avc_bridgeco_plug_type plug_type;
842                 unsigned int ch_count;
843 
844                 avc_bridgeco_fill_unit_addr(addr, plug_dir, AVC_BRIDGECO_PLUG_UNIT_EXT, i);
845 
846                 err = avc_bridgeco_get_plug_type(bebob->unit, addr, &plug_type);
847                 if (err < 0) {
848                         dev_err(&bebob->unit->device,
849                                 "fail to get type for external %d plug %d: %d\n",
850                                 plug_dir, i, err);
851                         break;
852                 } else if (plug_type != AVC_BRIDGECO_PLUG_TYPE_MIDI) {
853                         continue;
854                 }
855 
856                 err = avc_bridgeco_get_plug_ch_count(bebob->unit, addr, &ch_count);
857                 if (err < 0)
858                         break;
859                 // Yamaha GO44, GO46, Terratec Phase 24, Phase x24 reports 0 for the number of
860                 // channels in external output plug 3 (MIDI type) even if it has a pair of physical
861                 // MIDI jacks. As a workaround, assume it as one.
862                 if (ch_count == 0)
863                         ch_count = 1;
864                 *midi_ports += ch_count;
865         }
866 
867         return err;
868 }
869 
870 static int
871 seek_msu_sync_input_plug(struct snd_bebob *bebob)
872 {
873         u8 plugs[AVC_PLUG_INFO_BUF_BYTES], addr[AVC_BRIDGECO_ADDR_BYTES];
874         unsigned int i;
875         enum avc_bridgeco_plug_type type;
876         int err;
877 
878         /* Get the number of Music Sub Unit for both direction. */
879         err = avc_general_get_plug_info(bebob->unit, 0x0c, 0x00, 0x00, plugs);
880         if (err < 0) {
881                 dev_err(&bebob->unit->device,
882                         "fail to get info for MSU in/out plugs: %d\n",
883                         err);
884                 goto end;
885         }
886 
887         /* seek destination plugs for 'MSU sync input' */
888         bebob->sync_input_plug = -1;
889         for (i = 0; i < plugs[0]; i++) {
890                 avc_bridgeco_fill_msu_addr(addr, AVC_BRIDGECO_PLUG_DIR_IN, i);
891                 err = avc_bridgeco_get_plug_type(bebob->unit, addr, &type);
892                 if (err < 0) {
893                         dev_err(&bebob->unit->device,
894                                 "fail to get type for MSU in plug %d: %d\n",
895                                 i, err);
896                         goto end;
897                 }
898 
899                 if (type == AVC_BRIDGECO_PLUG_TYPE_SYNC) {
900                         bebob->sync_input_plug = i;
901                         break;
902                 }
903         }
904 end:
905         return err;
906 }
907 
908 int snd_bebob_stream_discover(struct snd_bebob *bebob)
909 {
910         const struct snd_bebob_clock_spec *clk_spec = bebob->spec->clock;
911         u8 plugs[AVC_PLUG_INFO_BUF_BYTES], addr[AVC_BRIDGECO_ADDR_BYTES];
912         int err;
913 
914         /* the number of plugs for isoc in/out, ext in/out  */
915         err = avc_general_get_plug_info(bebob->unit, 0x1f, 0x07, 0x00, plugs);
916         if (err < 0) {
917                 dev_err(&bebob->unit->device,
918                 "fail to get info for isoc/external in/out plugs: %d\n",
919                         err);
920                 goto end;
921         }
922 
923         /*
924          * This module supports at least one isoc input plug and one isoc
925          * output plug.
926          */
927         if ((plugs[0] == 0) || (plugs[1] == 0)) {
928                 err = -ENOSYS;
929                 goto end;
930         }
931 
932         err = fill_stream_formations(bebob, addr, AVC_BRIDGECO_PLUG_DIR_IN, 0,
933                                      bebob->rx_stream_formations);
934         if (err < 0)
935                 goto end;
936 
937         err = fill_stream_formations(bebob, addr, AVC_BRIDGECO_PLUG_DIR_OUT, 0,
938                                      bebob->tx_stream_formations);
939         if (err < 0)
940                 goto end;
941 
942         err = detect_midi_ports(bebob, bebob->tx_stream_formations, addr, AVC_BRIDGECO_PLUG_DIR_IN,
943                                 plugs[2], &bebob->midi_input_ports);
944         if (err < 0)
945                 goto end;
946 
947         err = detect_midi_ports(bebob, bebob->rx_stream_formations, addr, AVC_BRIDGECO_PLUG_DIR_OUT,
948                                 plugs[3], &bebob->midi_output_ports);
949         if (err < 0)
950                 goto end;
951 
952         /* for check source of clock later */
953         if (!clk_spec)
954                 err = seek_msu_sync_input_plug(bebob);
955 end:
956         return err;
957 }
958 
959 void snd_bebob_stream_lock_changed(struct snd_bebob *bebob)
960 {
961         bebob->dev_lock_changed = true;
962         wake_up(&bebob->hwdep_wait);
963 }
964 
965 int snd_bebob_stream_lock_try(struct snd_bebob *bebob)
966 {
967         int err;
968 
969         spin_lock_irq(&bebob->lock);
970 
971         /* user land lock this */
972         if (bebob->dev_lock_count < 0) {
973                 err = -EBUSY;
974                 goto end;
975         }
976 
977         /* this is the first time */
978         if (bebob->dev_lock_count++ == 0)
979                 snd_bebob_stream_lock_changed(bebob);
980         err = 0;
981 end:
982         spin_unlock_irq(&bebob->lock);
983         return err;
984 }
985 
986 void snd_bebob_stream_lock_release(struct snd_bebob *bebob)
987 {
988         spin_lock_irq(&bebob->lock);
989 
990         if (WARN_ON(bebob->dev_lock_count <= 0))
991                 goto end;
992         if (--bebob->dev_lock_count == 0)
993                 snd_bebob_stream_lock_changed(bebob);
994 end:
995         spin_unlock_irq(&bebob->lock);
996 }
997 

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