diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-08 18:07:14 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-08 18:07:14 -0400 |
commit | f5a246eab9a268f51ba8189ea5b098a1bfff200e (patch) | |
tree | a6ff7169e0bcaca498d9aec8b0624de1b74eaecb /sound/usb/endpoint.c | |
parent | d5bbd43d5f450c3fca058f5b85f3dfb4e8cc88c9 (diff) | |
parent | 7ff34ad80b7080fafaac8efa9ef0061708eddd51 (diff) |
Merge tag 'sound-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai:
"This contains pretty many small commits covering fairly large range of
files in sound/ directory. Partly because of additional API support
and partly because of constantly developed ASoC and ARM stuff.
Some highlights:
- Introduced the helper function and documentation for exposing the
channel map via control API, as discussed in Plumbers; most of PCI
drivers are covered, will follow more drivers later
- Most of drivers have been replaced with the new PM callbacks (if
the bus is supported)
- HD-audio controller got the support of runtime PM and the support
of D3 clock-stop. Also changing the power_save option in sysfs
kicks off immediately to enable / disable the power-save mode.
- Another significant code change in HD-audio is the rewrite of
firmware loading code. Other than that, most of changes in
HD-audio are continued cleanups and standardization for the generic
auto parser and bug fixes (HBR, device-specific fixups), in
addition to the support of channel-map API.
- Addition of ASoC bindings for the compressed API, used by the
mid-x86 drivers.
- Lots of cleanups and API refreshes for ASoC codec drivers and
DaVinci.
- Conversion of OMAP to dmaengine.
- New machine driver for Wolfson Microelectronics Bells.
- New CODEC driver for Wolfson Microelectronics WM0010.
- Enhancements to the ux500 and wm2000 drivers
- A new driver for DA9055 and the support for regulator bypass mode."
Fix up various arm soc header file reorg conflicts.
* tag 'sound-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (339 commits)
ALSA: hda - Add new codec ALC283 ALC290 support
ALSA: hda - avoid unneccesary indices on "Headphone Jack" controls
ALSA: hda - fix indices on boost volume on Conexant
ALSA: aloop - add locking to timer access
ALSA: hda - Fix hang caused by race during suspend.
sound: Remove unnecessary semicolon
ALSA: hda/realtek - Fix detection of ALC271X codec
ALSA: hda - Add inverted internal mic quirk for Lenovo IdeaPad U310
ALSA: hda - make Realtek/Sigmatel/Conexant use the generic unsol event
ALSA: hda - make a generic unsol event handler
ASoC: codecs: Add DA9055 codec driver
ASoC: eukrea-tlv320: Convert it to platform driver
ALSA: ASoC: add DT bindings for CS4271
ASoC: wm_hubs: Ensure volume updates are handled during class W startup
ASoC: wm5110: Adding missing volume update bits
ASoC: wm5110: Add OUT3R support
ASoC: wm5110: Add AEC loopback support
ASoC: wm5110: Rename EPOUT to HPOUT3
ASoC: arizona: Add more clock rates
ASoC: arizona: Add more DSP options for mixer input muxes
...
Diffstat (limited to 'sound/usb/endpoint.c')
-rw-r--r-- | sound/usb/endpoint.c | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 060dccb9ec75..7f78c6d782b0 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "card.h" | 31 | #include "card.h" |
32 | #include "endpoint.h" | 32 | #include "endpoint.h" |
33 | #include "pcm.h" | 33 | #include "pcm.h" |
34 | #include "quirks.h" | ||
34 | 35 | ||
35 | #define EP_FLAG_ACTIVATED 0 | 36 | #define EP_FLAG_ACTIVATED 0 |
36 | #define EP_FLAG_RUNNING 1 | 37 | #define EP_FLAG_RUNNING 1 |
@@ -170,6 +171,11 @@ static void retire_inbound_urb(struct snd_usb_endpoint *ep, | |||
170 | { | 171 | { |
171 | struct urb *urb = urb_ctx->urb; | 172 | struct urb *urb = urb_ctx->urb; |
172 | 173 | ||
174 | if (unlikely(ep->skip_packets > 0)) { | ||
175 | ep->skip_packets--; | ||
176 | return; | ||
177 | } | ||
178 | |||
173 | if (ep->sync_slave) | 179 | if (ep->sync_slave) |
174 | snd_usb_handle_sync_urb(ep->sync_slave, ep, urb); | 180 | snd_usb_handle_sync_urb(ep->sync_slave, ep, urb); |
175 | 181 | ||
@@ -567,20 +573,19 @@ static void release_urbs(struct snd_usb_endpoint *ep, int force) | |||
567 | * configure a data endpoint | 573 | * configure a data endpoint |
568 | */ | 574 | */ |
569 | static int data_ep_set_params(struct snd_usb_endpoint *ep, | 575 | static int data_ep_set_params(struct snd_usb_endpoint *ep, |
570 | struct snd_pcm_hw_params *hw_params, | 576 | snd_pcm_format_t pcm_format, |
577 | unsigned int channels, | ||
578 | unsigned int period_bytes, | ||
571 | struct audioformat *fmt, | 579 | struct audioformat *fmt, |
572 | struct snd_usb_endpoint *sync_ep) | 580 | struct snd_usb_endpoint *sync_ep) |
573 | { | 581 | { |
574 | unsigned int maxsize, i, urb_packs, total_packs, packs_per_ms; | 582 | unsigned int maxsize, i, urb_packs, total_packs, packs_per_ms; |
575 | int period_bytes = params_period_bytes(hw_params); | ||
576 | int format = params_format(hw_params); | ||
577 | int is_playback = usb_pipeout(ep->pipe); | 583 | int is_playback = usb_pipeout(ep->pipe); |
578 | int frame_bits = snd_pcm_format_physical_width(params_format(hw_params)) * | 584 | int frame_bits = snd_pcm_format_physical_width(pcm_format) * channels; |
579 | params_channels(hw_params); | ||
580 | 585 | ||
581 | ep->datainterval = fmt->datainterval; | 586 | ep->datainterval = fmt->datainterval; |
582 | ep->stride = frame_bits >> 3; | 587 | ep->stride = frame_bits >> 3; |
583 | ep->silence_value = format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0; | 588 | ep->silence_value = pcm_format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0; |
584 | 589 | ||
585 | /* calculate max. frequency */ | 590 | /* calculate max. frequency */ |
586 | if (ep->maxpacksize) { | 591 | if (ep->maxpacksize) { |
@@ -693,7 +698,6 @@ out_of_memory: | |||
693 | * configure a sync endpoint | 698 | * configure a sync endpoint |
694 | */ | 699 | */ |
695 | static int sync_ep_set_params(struct snd_usb_endpoint *ep, | 700 | static int sync_ep_set_params(struct snd_usb_endpoint *ep, |
696 | struct snd_pcm_hw_params *hw_params, | ||
697 | struct audioformat *fmt) | 701 | struct audioformat *fmt) |
698 | { | 702 | { |
699 | int i; | 703 | int i; |
@@ -736,7 +740,10 @@ out_of_memory: | |||
736 | * snd_usb_endpoint_set_params: configure an snd_usb_endpoint | 740 | * snd_usb_endpoint_set_params: configure an snd_usb_endpoint |
737 | * | 741 | * |
738 | * @ep: the snd_usb_endpoint to configure | 742 | * @ep: the snd_usb_endpoint to configure |
739 | * @hw_params: the hardware parameters | 743 | * @pcm_format: the audio fomat. |
744 | * @channels: the number of audio channels. | ||
745 | * @period_bytes: the number of bytes in one alsa period. | ||
746 | * @rate: the frame rate. | ||
740 | * @fmt: the USB audio format information | 747 | * @fmt: the USB audio format information |
741 | * @sync_ep: the sync endpoint to use, if any | 748 | * @sync_ep: the sync endpoint to use, if any |
742 | * | 749 | * |
@@ -745,7 +752,10 @@ out_of_memory: | |||
745 | * An endpoint that is already running can not be reconfigured. | 752 | * An endpoint that is already running can not be reconfigured. |
746 | */ | 753 | */ |
747 | int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, | 754 | int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, |
748 | struct snd_pcm_hw_params *hw_params, | 755 | snd_pcm_format_t pcm_format, |
756 | unsigned int channels, | ||
757 | unsigned int period_bytes, | ||
758 | unsigned int rate, | ||
749 | struct audioformat *fmt, | 759 | struct audioformat *fmt, |
750 | struct snd_usb_endpoint *sync_ep) | 760 | struct snd_usb_endpoint *sync_ep) |
751 | { | 761 | { |
@@ -765,9 +775,9 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, | |||
765 | ep->fill_max = !!(fmt->attributes & UAC_EP_CS_ATTR_FILL_MAX); | 775 | ep->fill_max = !!(fmt->attributes & UAC_EP_CS_ATTR_FILL_MAX); |
766 | 776 | ||
767 | if (snd_usb_get_speed(ep->chip->dev) == USB_SPEED_FULL) | 777 | if (snd_usb_get_speed(ep->chip->dev) == USB_SPEED_FULL) |
768 | ep->freqn = get_usb_full_speed_rate(params_rate(hw_params)); | 778 | ep->freqn = get_usb_full_speed_rate(rate); |
769 | else | 779 | else |
770 | ep->freqn = get_usb_high_speed_rate(params_rate(hw_params)); | 780 | ep->freqn = get_usb_high_speed_rate(rate); |
771 | 781 | ||
772 | /* calculate the frequency in 16.16 format */ | 782 | /* calculate the frequency in 16.16 format */ |
773 | ep->freqm = ep->freqn; | 783 | ep->freqm = ep->freqn; |
@@ -777,10 +787,11 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, | |||
777 | 787 | ||
778 | switch (ep->type) { | 788 | switch (ep->type) { |
779 | case SND_USB_ENDPOINT_TYPE_DATA: | 789 | case SND_USB_ENDPOINT_TYPE_DATA: |
780 | err = data_ep_set_params(ep, hw_params, fmt, sync_ep); | 790 | err = data_ep_set_params(ep, pcm_format, channels, |
791 | period_bytes, fmt, sync_ep); | ||
781 | break; | 792 | break; |
782 | case SND_USB_ENDPOINT_TYPE_SYNC: | 793 | case SND_USB_ENDPOINT_TYPE_SYNC: |
783 | err = sync_ep_set_params(ep, hw_params, fmt); | 794 | err = sync_ep_set_params(ep, fmt); |
784 | break; | 795 | break; |
785 | default: | 796 | default: |
786 | err = -EINVAL; | 797 | err = -EINVAL; |
@@ -828,6 +839,8 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, int can_sleep) | |||
828 | ep->unlink_mask = 0; | 839 | ep->unlink_mask = 0; |
829 | ep->phase = 0; | 840 | ep->phase = 0; |
830 | 841 | ||
842 | snd_usb_endpoint_start_quirk(ep); | ||
843 | |||
831 | /* | 844 | /* |
832 | * If this endpoint has a data endpoint as implicit feedback source, | 845 | * If this endpoint has a data endpoint as implicit feedback source, |
833 | * don't start the urbs here. Instead, mark them all as available, | 846 | * don't start the urbs here. Instead, mark them all as available, |