aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb')
-rw-r--r--sound/usb/usbaudio.c45
1 files changed, 26 insertions, 19 deletions
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 56e42b88addf..8fd37596e3a1 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -186,6 +186,7 @@ struct snd_usb_substream {
186 u64 formats; /* format bitmasks (all or'ed) */ 186 u64 formats; /* format bitmasks (all or'ed) */
187 unsigned int num_formats; /* number of supported audio formats (list) */ 187 unsigned int num_formats; /* number of supported audio formats (list) */
188 struct list_head fmt_list; /* format list */ 188 struct list_head fmt_list; /* format list */
189 struct snd_pcm_hw_constraint_list rate_list; /* limited rates */
189 spinlock_t lock; 190 spinlock_t lock;
190 191
191 struct snd_urb_ops ops; /* callbacks (must be filled at init) */ 192 struct snd_urb_ops ops; /* callbacks (must be filled at init) */
@@ -1818,28 +1819,33 @@ static int check_hw_params_convention(struct snd_usb_substream *subs)
1818static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime, 1819static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime,
1819 struct snd_usb_substream *subs) 1820 struct snd_usb_substream *subs)
1820{ 1821{
1821 struct list_head *p; 1822 struct audioformat *fp;
1822 struct snd_pcm_hw_constraint_list constraints_rates; 1823 int count = 0, needs_knot = 0;
1823 int err; 1824 int err;
1824 1825
1825 list_for_each(p, &subs->fmt_list) { 1826 list_for_each_entry(fp, &subs->fmt_list, list) {
1826 struct audioformat *fp; 1827 if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS)
1827 fp = list_entry(p, struct audioformat, list); 1828 return 0;
1828 1829 count += fp->nr_rates;
1829 if (!fp->needs_knot) 1830 if (fp->needs_knot)
1830 continue; 1831 needs_knot = 1;
1831
1832 constraints_rates.count = fp->nr_rates;
1833 constraints_rates.list = fp->rate_table;
1834 constraints_rates.mask = 0;
1835
1836 err = snd_pcm_hw_constraint_list(runtime, 0,
1837 SNDRV_PCM_HW_PARAM_RATE,
1838 &constraints_rates);
1839
1840 if (err < 0)
1841 return err;
1842 } 1832 }
1833 if (!needs_knot)
1834 return 0;
1835
1836 subs->rate_list.count = count;
1837 subs->rate_list.list = kmalloc(sizeof(int) * count, GFP_KERNEL);
1838 subs->rate_list.mask = 0;
1839 count = 0;
1840 list_for_each_entry(fp, &subs->fmt_list, list) {
1841 int i;
1842 for (i = 0; i < fp->nr_rates; i++)
1843 subs->rate_list.list[count++] = fp->rate_table[i];
1844 }
1845 err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1846 &subs->rate_list);
1847 if (err < 0)
1848 return err;
1843 1849
1844 return 0; 1850 return 0;
1845} 1851}
@@ -2238,6 +2244,7 @@ static void free_substream(struct snd_usb_substream *subs)
2238 kfree(fp->rate_table); 2244 kfree(fp->rate_table);
2239 kfree(fp); 2245 kfree(fp);
2240 } 2246 }
2247 kfree(subs->rate_list.list);
2241} 2248}
2242 2249
2243 2250