diff options
author | Daniel Mack <zonque@gmail.com> | 2012-04-12 07:51:15 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-04-13 04:25:24 -0400 |
commit | 94c27215bc5b7941a52d3d3a02d904bfdcd5fe5e (patch) | |
tree | a9dd1c93b1079d61bbbc62f28cc4176736583185 /sound | |
parent | c75a8a7ae565d7cd9baa87a504ba9162e355b4b0 (diff) |
ALSA: snd-usb: add some documentation
Document the new streaming code and some of the functions so that
contributers can catch up easier.
Signed-off-by: Daniel Mack <zonque@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/usb/endpoint.c | 182 |
1 files changed, 171 insertions, 11 deletions
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 64853f76c10c..d1ef3048dbba 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c | |||
@@ -36,6 +36,32 @@ | |||
36 | #define EP_FLAG_RUNNING 1 | 36 | #define EP_FLAG_RUNNING 1 |
37 | 37 | ||
38 | /* | 38 | /* |
39 | * snd_usb_endpoint is a model that abstracts everything related to an | ||
40 | * USB endpoint and its streaming. | ||
41 | * | ||
42 | * There are functions to activate and deactivate the streaming URBs and | ||
43 | * optinal callbacks to let the pcm logic handle the actual content of the | ||
44 | * packets for playback and record. Thus, the bus streaming and the audio | ||
45 | * handlers are fully decoupled. | ||
46 | * | ||
47 | * There are two different types of endpoints in for audio applications. | ||
48 | * | ||
49 | * SND_USB_ENDPOINT_TYPE_DATA handles full audio data payload for both | ||
50 | * inbound and outbound traffic. | ||
51 | * | ||
52 | * SND_USB_ENDPOINT_TYPE_SYNC are for inbound traffic only and expect the | ||
53 | * payload to carry Q16.16 formatted sync information (3 or 4 bytes). | ||
54 | * | ||
55 | * Each endpoint has to be configured (by calling | ||
56 | * snd_usb_endpoint_set_params()) before it can be used. | ||
57 | * | ||
58 | * The model incorporates a reference counting, so that multiple users | ||
59 | * can call snd_usb_endpoint_start() and snd_usb_endpoint_stop(), and | ||
60 | * only the first user will effectively start the URBs, and only the last | ||
61 | * one will tear them down again. | ||
62 | */ | ||
63 | |||
64 | /* | ||
39 | * convert a sampling rate into our full speed format (fs/1000 in Q16.16) | 65 | * convert a sampling rate into our full speed format (fs/1000 in Q16.16) |
40 | * this will overflow at approx 524 kHz | 66 | * this will overflow at approx 524 kHz |
41 | */ | 67 | */ |
@@ -91,6 +117,14 @@ static const char *usb_error_string(int err) | |||
91 | } | 117 | } |
92 | } | 118 | } |
93 | 119 | ||
120 | /** | ||
121 | * snd_usb_endpoint_implicit_feedback_sink: Report endpoint usage type | ||
122 | * | ||
123 | * @ep: The endpoint | ||
124 | * | ||
125 | * Determine whether an endpoint is driven by an implicit feedback | ||
126 | * data endpoint source. | ||
127 | */ | ||
94 | int snd_usb_endpoint_implict_feedback_sink(struct snd_usb_endpoint *ep) | 128 | int snd_usb_endpoint_implict_feedback_sink(struct snd_usb_endpoint *ep) |
95 | { | 129 | { |
96 | return ep->sync_master && | 130 | return ep->sync_master && |
@@ -99,7 +133,13 @@ int snd_usb_endpoint_implict_feedback_sink(struct snd_usb_endpoint *ep) | |||
99 | usb_pipeout(ep->pipe); | 133 | usb_pipeout(ep->pipe); |
100 | } | 134 | } |
101 | 135 | ||
102 | /* determine the number of frames in the next packet */ | 136 | /* |
137 | * For streaming based on information derived from sync endpoints, | ||
138 | * prepare_outbound_urb_sizes() will call next_packet_size() to | ||
139 | * determine the number of samples to be sent in the next packet. | ||
140 | * | ||
141 | * For implicit feedback, next_packet_size() is unused. | ||
142 | */ | ||
103 | static int next_packet_size(struct snd_usb_endpoint *ep) | 143 | static int next_packet_size(struct snd_usb_endpoint *ep) |
104 | { | 144 | { |
105 | unsigned long flags; | 145 | unsigned long flags; |
@@ -237,6 +277,19 @@ static inline void prepare_inbound_urb(struct snd_usb_endpoint *ep, | |||
237 | } | 277 | } |
238 | } | 278 | } |
239 | 279 | ||
280 | /* | ||
281 | * Send output urbs that have been prepared previously. Urbs are dequeued | ||
282 | * from ep->ready_playback_urbs and in case there there aren't any available | ||
283 | * or there are no packets that have been prepared, this function does | ||
284 | * nothing. | ||
285 | * | ||
286 | * The reason why the functionality of sending and preparing urbs is separated | ||
287 | * is that host controllers don't guarantee an ordering in returing inbound | ||
288 | * and outbound packets to their submitters. | ||
289 | * | ||
290 | * This function is only used for implicit feedback endpoints. For endpoints | ||
291 | * driven by sync endpoints, urbs are submitted from their completion handler. | ||
292 | */ | ||
240 | static void queue_pending_output_urbs(struct snd_usb_endpoint *ep) | 293 | static void queue_pending_output_urbs(struct snd_usb_endpoint *ep) |
241 | { | 294 | { |
242 | while (test_bit(EP_FLAG_RUNNING, &ep->flags)) { | 295 | while (test_bit(EP_FLAG_RUNNING, &ep->flags)) { |
@@ -270,6 +323,7 @@ static void queue_pending_output_urbs(struct snd_usb_endpoint *ep) | |||
270 | for (i = 0; i < packet->packets; i++) | 323 | for (i = 0; i < packet->packets; i++) |
271 | ctx->packet_size[i] = packet->packet_size[i]; | 324 | ctx->packet_size[i] = packet->packet_size[i]; |
272 | 325 | ||
326 | /* call the data handler to fill in playback data */ | ||
273 | prepare_outbound_urb(ep, ctx); | 327 | prepare_outbound_urb(ep, ctx); |
274 | 328 | ||
275 | err = usb_submit_urb(ctx->urb, GFP_ATOMIC); | 329 | err = usb_submit_urb(ctx->urb, GFP_ATOMIC); |
@@ -336,6 +390,22 @@ exit_clear: | |||
336 | clear_bit(ctx->index, &ep->active_mask); | 390 | clear_bit(ctx->index, &ep->active_mask); |
337 | } | 391 | } |
338 | 392 | ||
393 | /** | ||
394 | * snd_usb_add_endpoint: Add an endpoint to an audio chip | ||
395 | * | ||
396 | * @chip: The chip | ||
397 | * @alts: The USB host interface | ||
398 | * @ep_num: The number of the endpoint to use | ||
399 | * @direction: SNDRV_PCM_STREAM_PLAYBACK or SNDRV_PCM_STREAM_CAPTURE | ||
400 | * @type: SND_USB_ENDPOINT_TYPE_DATA or SND_USB_ENDPOINT_TYPE_SYNC | ||
401 | * | ||
402 | * If the requested endpoint has not been added to the given chip before, | ||
403 | * a new instance is created. Otherwise, a pointer to the previoulsy | ||
404 | * created instance is returned. In case of any error, NULL is returned. | ||
405 | * | ||
406 | * New endpoints will be added to chip->ep_list and must be freed by | ||
407 | * calling snd_usb_endpoint_free(). | ||
408 | */ | ||
339 | struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip, | 409 | struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip, |
340 | struct usb_host_interface *alts, | 410 | struct usb_host_interface *alts, |
341 | int ep_num, int direction, int type) | 411 | int ep_num, int direction, int type) |
@@ -506,6 +576,9 @@ static void release_urbs(struct snd_usb_endpoint *ep, int force) | |||
506 | ep->nurbs = 0; | 576 | ep->nurbs = 0; |
507 | } | 577 | } |
508 | 578 | ||
579 | /* | ||
580 | * configure a data endpoint | ||
581 | */ | ||
509 | static int data_ep_set_params(struct snd_usb_endpoint *ep, | 582 | static int data_ep_set_params(struct snd_usb_endpoint *ep, |
510 | struct snd_pcm_hw_params *hw_params, | 583 | struct snd_pcm_hw_params *hw_params, |
511 | struct audioformat *fmt, | 584 | struct audioformat *fmt, |
@@ -629,6 +702,9 @@ out_of_memory: | |||
629 | return -ENOMEM; | 702 | return -ENOMEM; |
630 | } | 703 | } |
631 | 704 | ||
705 | /* | ||
706 | * configure a sync endpoint | ||
707 | */ | ||
632 | static int sync_ep_set_params(struct snd_usb_endpoint *ep, | 708 | static int sync_ep_set_params(struct snd_usb_endpoint *ep, |
633 | struct snd_pcm_hw_params *hw_params, | 709 | struct snd_pcm_hw_params *hw_params, |
634 | struct audioformat *fmt) | 710 | struct audioformat *fmt) |
@@ -669,6 +745,15 @@ out_of_memory: | |||
669 | return -ENOMEM; | 745 | return -ENOMEM; |
670 | } | 746 | } |
671 | 747 | ||
748 | /** | ||
749 | * snd_usb_endpoint_set_params: configure an snd_endpoint | ||
750 | * | ||
751 | * @ep: the endpoint to configure | ||
752 | * | ||
753 | * Determine the number of of URBs to be used on this endpoint. | ||
754 | * An endpoint must be configured before it can be started. | ||
755 | * An endpoint that is already running can not be reconfigured. | ||
756 | */ | ||
672 | int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, | 757 | int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, |
673 | struct snd_pcm_hw_params *hw_params, | 758 | struct snd_pcm_hw_params *hw_params, |
674 | struct audioformat *fmt, | 759 | struct audioformat *fmt, |
@@ -717,6 +802,19 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, | |||
717 | return err; | 802 | return err; |
718 | } | 803 | } |
719 | 804 | ||
805 | /** | ||
806 | * snd_usb_endpoint_start: start an snd_usb_endpoint | ||
807 | * | ||
808 | * @ep: the endpoint to start | ||
809 | * | ||
810 | * A call to this function will increment the use count of the endpoint. | ||
811 | * In case this not already running, the URBs for this endpoint will be | ||
812 | * submitted. Otherwise, this function does nothing. | ||
813 | * | ||
814 | * Must be balanced to calls of snd_usb_endpoint_stop(). | ||
815 | * | ||
816 | * Returns an error if the URB submission failed, 0 in all other cases. | ||
817 | */ | ||
720 | int snd_usb_endpoint_start(struct snd_usb_endpoint *ep) | 818 | int snd_usb_endpoint_start(struct snd_usb_endpoint *ep) |
721 | { | 819 | { |
722 | int err; | 820 | int err; |
@@ -788,6 +886,17 @@ __error: | |||
788 | return -EPIPE; | 886 | return -EPIPE; |
789 | } | 887 | } |
790 | 888 | ||
889 | /** | ||
890 | * snd_usb_endpoint_stop: stop an snd_usb_endpoint | ||
891 | * | ||
892 | * @ep: the endpoint to stop (may be NULL) | ||
893 | * | ||
894 | * A call to this function will decrement the use count of the endpoint. | ||
895 | * In case the last user has requested the endpoint stop, the URBs will | ||
896 | * actually deactivated. | ||
897 | * | ||
898 | * Must be balanced to calls of snd_usb_endpoint_start(). | ||
899 | */ | ||
791 | void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, | 900 | void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, |
792 | int force, int can_sleep, int wait) | 901 | int force, int can_sleep, int wait) |
793 | { | 902 | { |
@@ -812,6 +921,19 @@ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, | |||
812 | } | 921 | } |
813 | } | 922 | } |
814 | 923 | ||
924 | /** | ||
925 | * snd_usb_endpoint_activate: activate an snd_usb_endpoint | ||
926 | * | ||
927 | * @ep: the endpoint to activate | ||
928 | * | ||
929 | * If the endpoint is not currently in use, this functions will select the | ||
930 | * correct alternate interface setting for the interface of this endpoint. | ||
931 | * | ||
932 | * In case of any active users, this functions does nothing. | ||
933 | * | ||
934 | * Returns an error if usb_set_interface() failed, 0 in all other | ||
935 | * cases. | ||
936 | */ | ||
815 | int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep) | 937 | int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep) |
816 | { | 938 | { |
817 | if (ep->use_count != 0) | 939 | if (ep->use_count != 0) |
@@ -835,6 +957,19 @@ int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep) | |||
835 | return -EBUSY; | 957 | return -EBUSY; |
836 | } | 958 | } |
837 | 959 | ||
960 | /** | ||
961 | * snd_usb_endpoint_deactivate: deactivate an snd_usb_endpoint | ||
962 | * | ||
963 | * @ep: the endpoint to deactivate | ||
964 | * | ||
965 | * If the endpoint is not currently in use, this functions will select the | ||
966 | * alternate interface setting 0 for the interface of this endpoint. | ||
967 | * | ||
968 | * In case of any active users, this functions does nothing. | ||
969 | * | ||
970 | * Returns an error if usb_set_interface() failed, 0 in all other | ||
971 | * cases. | ||
972 | */ | ||
838 | int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep) | 973 | int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep) |
839 | { | 974 | { |
840 | if (!ep) | 975 | if (!ep) |
@@ -860,6 +995,13 @@ int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep) | |||
860 | return -EBUSY; | 995 | return -EBUSY; |
861 | } | 996 | } |
862 | 997 | ||
998 | /** snd_usb_endpoint_free: Free the resources of an snd_usb_endpoint | ||
999 | * | ||
1000 | * @ep: the list header of the endpoint to free | ||
1001 | * | ||
1002 | * This function does not care for the endpoint's use count but will tear | ||
1003 | * down all the streaming URBs immediately and free all resources. | ||
1004 | */ | ||
863 | void snd_usb_endpoint_free(struct list_head *head) | 1005 | void snd_usb_endpoint_free(struct list_head *head) |
864 | { | 1006 | { |
865 | struct snd_usb_endpoint *ep; | 1007 | struct snd_usb_endpoint *ep; |
@@ -869,15 +1011,15 @@ void snd_usb_endpoint_free(struct list_head *head) | |||
869 | kfree(ep); | 1011 | kfree(ep); |
870 | } | 1012 | } |
871 | 1013 | ||
872 | /* | 1014 | /** |
873 | * process after playback sync complete | 1015 | * snd_usb_handle_sync_urb: parse an USB sync packet |
874 | * | 1016 | * |
875 | * Full speed devices report feedback values in 10.14 format as samples per | 1017 | * @ep: the endpoint to handle the packet |
876 | * frame, high speed devices in 16.16 format as samples per microframe. | 1018 | * @sender: the sending endpoint |
877 | * Because the Audio Class 1 spec was written before USB 2.0, many high speed | 1019 | * @urb: the received packet |
878 | * devices use a wrong interpretation, some others use an entirely different | 1020 | * |
879 | * format. Therefore, we cannot predict what format any particular device uses | 1021 | * This function is called from the context of an endpoint that received |
880 | * and must detect it automatically. | 1022 | * the packet and is used to let another endpoint object handle the payload. |
881 | */ | 1023 | */ |
882 | void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep, | 1024 | void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep, |
883 | struct snd_usb_endpoint *sender, | 1025 | struct snd_usb_endpoint *sender, |
@@ -889,6 +1031,11 @@ void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep, | |||
889 | 1031 | ||
890 | snd_BUG_ON(ep == sender); | 1032 | snd_BUG_ON(ep == sender); |
891 | 1033 | ||
1034 | /* | ||
1035 | * In case the endpoint is operating in implicit feedback mode, prepare | ||
1036 | * and a new outbound URB that has the same layout as the received | ||
1037 | * packet and add it to the list of pending urbs. | ||
1038 | */ | ||
892 | if (snd_usb_endpoint_implict_feedback_sink(ep) && | 1039 | if (snd_usb_endpoint_implict_feedback_sink(ep) && |
893 | ep->use_count != 0) { | 1040 | ep->use_count != 0) { |
894 | 1041 | ||
@@ -938,7 +1085,20 @@ void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep, | |||
938 | return; | 1085 | return; |
939 | } | 1086 | } |
940 | 1087 | ||
941 | /* parse sync endpoint packet */ | 1088 | /* |
1089 | * process after playback sync complete | ||
1090 | * | ||
1091 | * Full speed devices report feedback values in 10.14 format as samples | ||
1092 | * per frame, high speed devices in 16.16 format as samples per | ||
1093 | * microframe. | ||
1094 | * | ||
1095 | * Because the Audio Class 1 spec was written before USB 2.0, many high | ||
1096 | * speed devices use a wrong interpretation, some others use an | ||
1097 | * entirely different format. | ||
1098 | * | ||
1099 | * Therefore, we cannot predict what format any particular device uses | ||
1100 | * and must detect it automatically. | ||
1101 | */ | ||
942 | 1102 | ||
943 | if (urb->iso_frame_desc[0].status != 0 || | 1103 | if (urb->iso_frame_desc[0].status != 0 || |
944 | urb->iso_frame_desc[0].actual_length < 3) | 1104 | urb->iso_frame_desc[0].actual_length < 3) |