aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/usb/usbaudio.c135
1 files changed, 19 insertions, 116 deletions
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 175c7d1da5cf..b7fa0b0b713d 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -1736,97 +1736,6 @@ static int hw_rule_format(struct snd_pcm_hw_params *params,
1736 return changed; 1736 return changed;
1737} 1737}
1738 1738
1739#define MAX_MASK 64
1740
1741/*
1742 * check whether the registered audio formats need special hw-constraints
1743 */
1744static int check_hw_params_convention(struct snd_usb_substream *subs)
1745{
1746 int i;
1747 u32 *channels;
1748 u32 *rates;
1749 u32 cmaster, rmaster;
1750 u32 rate_min = 0, rate_max = 0;
1751 struct list_head *p;
1752 int err = 1;
1753
1754 channels = kcalloc(MAX_MASK, sizeof(u32), GFP_KERNEL);
1755 rates = kcalloc(MAX_MASK, sizeof(u32), GFP_KERNEL);
1756 if (!channels || !rates) {
1757 err = -ENOMEM;
1758 goto __out;
1759 }
1760
1761 list_for_each(p, &subs->fmt_list) {
1762 struct audioformat *f;
1763 f = list_entry(p, struct audioformat, list);
1764 /* unconventional channels? */
1765 if (f->channels > 32)
1766 goto __out;
1767 /* continuous rate min/max matches? */
1768 if (f->rates & SNDRV_PCM_RATE_CONTINUOUS) {
1769 if (rate_min && f->rate_min != rate_min)
1770 goto __out;
1771 if (rate_max && f->rate_max != rate_max)
1772 goto __out;
1773 rate_min = f->rate_min;
1774 rate_max = f->rate_max;
1775 }
1776 /* combination of continuous rates and fixed rates? */
1777 if (rates[f->format] & SNDRV_PCM_RATE_CONTINUOUS) {
1778 if (f->rates != rates[f->format])
1779 goto __out;
1780 }
1781 if (f->rates & SNDRV_PCM_RATE_CONTINUOUS) {
1782 if (rates[f->format] && rates[f->format] != f->rates)
1783 goto __out;
1784 }
1785 channels[f->format] |= 1 << (f->channels - 1);
1786 rates[f->format] |= f->rates;
1787 /* needs knot? */
1788 if (f->rates & SNDRV_PCM_RATE_KNOT)
1789 goto __out;
1790 }
1791 /* check whether channels and rates match for all formats */
1792 cmaster = rmaster = 0;
1793 for (i = 0; i < MAX_MASK; i++) {
1794 if (cmaster != channels[i] && cmaster && channels[i])
1795 goto __out;
1796 if (rmaster != rates[i] && rmaster && rates[i])
1797 goto __out;
1798 if (channels[i])
1799 cmaster = channels[i];
1800 if (rates[i])
1801 rmaster = rates[i];
1802 }
1803 /* check whether channels match for all distinct rates */
1804 memset(channels, 0, MAX_MASK * sizeof(u32));
1805 list_for_each(p, &subs->fmt_list) {
1806 struct audioformat *f;
1807 f = list_entry(p, struct audioformat, list);
1808 if (f->rates & SNDRV_PCM_RATE_CONTINUOUS)
1809 continue;
1810 for (i = 0; i < 32; i++) {
1811 if (f->rates & (1 << i))
1812 channels[i] |= 1 << (f->channels - 1);
1813 }
1814 }
1815 cmaster = 0;
1816 for (i = 0; i < 32; i++) {
1817 if (cmaster != channels[i] && cmaster && channels[i])
1818 goto __out;
1819 if (channels[i])
1820 cmaster = channels[i];
1821 }
1822 err = 0;
1823
1824 __out:
1825 kfree(channels);
1826 kfree(rates);
1827 return err;
1828}
1829
1830/* 1739/*
1831 * If the device supports unusual bit rates, does the request meet these? 1740 * If the device supports unusual bit rates, does the request meet these?
1832 */ 1741 */
@@ -1909,32 +1818,26 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre
1909 1000, 1818 1000,
1910 /*(nrpacks * MAX_URBS) * 1000*/ UINT_MAX); 1819 /*(nrpacks * MAX_URBS) * 1000*/ UINT_MAX);
1911 1820
1912 err = check_hw_params_convention(subs); 1821 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1913 if (err < 0) 1822 hw_rule_rate, subs,
1823 SNDRV_PCM_HW_PARAM_FORMAT,
1824 SNDRV_PCM_HW_PARAM_CHANNELS,
1825 -1)) < 0)
1826 return err;
1827 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
1828 hw_rule_channels, subs,
1829 SNDRV_PCM_HW_PARAM_FORMAT,
1830 SNDRV_PCM_HW_PARAM_RATE,
1831 -1)) < 0)
1832 return err;
1833 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
1834 hw_rule_format, subs,
1835 SNDRV_PCM_HW_PARAM_RATE,
1836 SNDRV_PCM_HW_PARAM_CHANNELS,
1837 -1)) < 0)
1838 return err;
1839 if ((err = snd_usb_pcm_check_knot(runtime, subs)) < 0)
1914 return err; 1840 return err;
1915 else if (err) {
1916 hwc_debug("setting extra hw constraints...\n");
1917 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1918 hw_rule_rate, subs,
1919 SNDRV_PCM_HW_PARAM_FORMAT,
1920 SNDRV_PCM_HW_PARAM_CHANNELS,
1921 -1)) < 0)
1922 return err;
1923 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
1924 hw_rule_channels, subs,
1925 SNDRV_PCM_HW_PARAM_FORMAT,
1926 SNDRV_PCM_HW_PARAM_RATE,
1927 -1)) < 0)
1928 return err;
1929 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
1930 hw_rule_format, subs,
1931 SNDRV_PCM_HW_PARAM_RATE,
1932 SNDRV_PCM_HW_PARAM_CHANNELS,
1933 -1)) < 0)
1934 return err;
1935 if ((err = snd_usb_pcm_check_knot(runtime, subs)) < 0)
1936 return err;
1937 }
1938 return 0; 1841 return 0;
1939} 1842}
1940 1843