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/usb | |
| 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/usb')
| -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) |
