aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2009-04-03 03:48:26 -0400
committerTakashi Iwai <tiwai@suse.de>2009-04-06 22:11:28 -0400
commita7d9c0990d5503775784fef7ff44d74d7e3294fd (patch)
treeaf61abe757897db23d2266506db75d241f586948 /sound
parent744b89e542b9a16c9afb8a88f623fbe059c88ccb (diff)
sound: usb-audio: allow period sizes less than 1 ms
To enable periods shorter than 1 ms, we have to make sure that short periods are only available for alternate settings that have a small enough data packet interval. Furthermore, the code that aligns URBs to USB frames is now superfluous. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/usb/usbaudio.c106
1 files changed, 86 insertions, 20 deletions
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 3f974a64c55e..823296d7d578 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -171,7 +171,6 @@ struct snd_usb_substream {
171 unsigned int curframesize; /* current packet size in frames (for capture) */ 171 unsigned int curframesize; /* current packet size in frames (for capture) */
172 unsigned int fill_max: 1; /* fill max packet size always */ 172 unsigned int fill_max: 1; /* fill max packet size always */
173 unsigned int fmt_type; /* USB audio format type (1-3) */ 173 unsigned int fmt_type; /* USB audio format type (1-3) */
174 unsigned int packs_per_ms; /* packets per millisecond (for playback) */
175 174
176 unsigned int running: 1; /* running status */ 175 unsigned int running: 1; /* running status */
177 176
@@ -608,9 +607,7 @@ static int prepare_playback_urb(struct snd_usb_substream *subs,
608 break; 607 break;
609 } 608 }
610 } 609 }
611 /* finish at the frame boundary at/after the period boundary */ 610 if (period_elapsed) /* finish at the period boundary */
612 if (period_elapsed &&
613 (i & (subs->packs_per_ms - 1)) == subs->packs_per_ms - 1)
614 break; 611 break;
615 } 612 }
616 if (subs->hwptr_done + offs > runtime->buffer_size) { 613 if (subs->hwptr_done + offs > runtime->buffer_size) {
@@ -1068,7 +1065,6 @@ static int init_substream_urbs(struct snd_usb_substream *subs, unsigned int peri
1068 packs_per_ms = 8 >> subs->datainterval; 1065 packs_per_ms = 8 >> subs->datainterval;
1069 else 1066 else
1070 packs_per_ms = 1; 1067 packs_per_ms = 1;
1071 subs->packs_per_ms = packs_per_ms;
1072 1068
1073 if (is_playback) { 1069 if (is_playback) {
1074 urb_packs = max(nrpacks, 1); 1070 urb_packs = max(nrpacks, 1);
@@ -1088,18 +1084,17 @@ static int init_substream_urbs(struct snd_usb_substream *subs, unsigned int peri
1088 minsize -= minsize >> 3; 1084 minsize -= minsize >> 3;
1089 minsize = max(minsize, 1u); 1085 minsize = max(minsize, 1u);
1090 total_packs = (period_bytes + minsize - 1) / minsize; 1086 total_packs = (period_bytes + minsize - 1) / minsize;
1091 /* round up to multiple of packs_per_ms */
1092 total_packs = (total_packs + packs_per_ms - 1)
1093 & ~(packs_per_ms - 1);
1094 /* we need at least two URBs for queueing */ 1087 /* we need at least two URBs for queueing */
1095 if (total_packs < 2 * packs_per_ms) { 1088 if (total_packs < 2) {
1096 total_packs = 2 * packs_per_ms; 1089 total_packs = 2;
1097 } else { 1090 } else {
1098 /* and we don't want too long a queue either */ 1091 /* and we don't want too long a queue either */
1099 maxpacks = max(MAX_QUEUE * packs_per_ms, urb_packs * 2); 1092 maxpacks = max(MAX_QUEUE * packs_per_ms, urb_packs * 2);
1100 total_packs = min(total_packs, maxpacks); 1093 total_packs = min(total_packs, maxpacks);
1101 } 1094 }
1102 } else { 1095 } else {
1096 while (urb_packs > 1 && urb_packs * maxsize >= period_bytes)
1097 urb_packs >>= 1;
1103 total_packs = MAX_URBS * urb_packs; 1098 total_packs = MAX_URBS * urb_packs;
1104 } 1099 }
1105 subs->nurbs = (total_packs + urb_packs - 1) / urb_packs; 1100 subs->nurbs = (total_packs + urb_packs - 1) / urb_packs;
@@ -1564,11 +1559,15 @@ static struct snd_pcm_hardware snd_usb_hardware =
1564#define hwc_debug(fmt, args...) /**/ 1559#define hwc_debug(fmt, args...) /**/
1565#endif 1560#endif
1566 1561
1567static int hw_check_valid_format(struct snd_pcm_hw_params *params, struct audioformat *fp) 1562static int hw_check_valid_format(struct snd_usb_substream *subs,
1563 struct snd_pcm_hw_params *params,
1564 struct audioformat *fp)
1568{ 1565{
1569 struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); 1566 struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
1570 struct snd_interval *ct = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); 1567 struct snd_interval *ct = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
1571 struct snd_mask *fmts = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); 1568 struct snd_mask *fmts = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
1569 struct snd_interval *pt = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME);
1570 unsigned int ptime;
1572 1571
1573 /* check the format */ 1572 /* check the format */
1574 if (!snd_mask_test(fmts, fp->format)) { 1573 if (!snd_mask_test(fmts, fp->format)) {
@@ -1589,6 +1588,14 @@ static int hw_check_valid_format(struct snd_pcm_hw_params *params, struct audiof
1589 hwc_debug(" > check: rate_max %d < min %d\n", fp->rate_max, it->min); 1588 hwc_debug(" > check: rate_max %d < min %d\n", fp->rate_max, it->min);
1590 return 0; 1589 return 0;
1591 } 1590 }
1591 /* check whether the period time is >= the data packet interval */
1592 if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH) {
1593 ptime = 125 * (1 << fp->datainterval);
1594 if (ptime > pt->max || (ptime == pt->max && pt->openmax)) {
1595 hwc_debug(" > check: ptime %u > max %u\n", ptime, pt->max);
1596 return 0;
1597 }
1598 }
1592 return 1; 1599 return 1;
1593} 1600}
1594 1601
@@ -1607,7 +1614,7 @@ static int hw_rule_rate(struct snd_pcm_hw_params *params,
1607 list_for_each(p, &subs->fmt_list) { 1614 list_for_each(p, &subs->fmt_list) {
1608 struct audioformat *fp; 1615 struct audioformat *fp;
1609 fp = list_entry(p, struct audioformat, list); 1616 fp = list_entry(p, struct audioformat, list);
1610 if (!hw_check_valid_format(params, fp)) 1617 if (!hw_check_valid_format(subs, params, fp))
1611 continue; 1618 continue;
1612 if (changed++) { 1619 if (changed++) {
1613 if (rmin > fp->rate_min) 1620 if (rmin > fp->rate_min)
@@ -1661,7 +1668,7 @@ static int hw_rule_channels(struct snd_pcm_hw_params *params,
1661 list_for_each(p, &subs->fmt_list) { 1668 list_for_each(p, &subs->fmt_list) {
1662 struct audioformat *fp; 1669 struct audioformat *fp;
1663 fp = list_entry(p, struct audioformat, list); 1670 fp = list_entry(p, struct audioformat, list);
1664 if (!hw_check_valid_format(params, fp)) 1671 if (!hw_check_valid_format(subs, params, fp))
1665 continue; 1672 continue;
1666 if (changed++) { 1673 if (changed++) {
1667 if (rmin > fp->channels) 1674 if (rmin > fp->channels)
@@ -1714,7 +1721,7 @@ static int hw_rule_format(struct snd_pcm_hw_params *params,
1714 list_for_each(p, &subs->fmt_list) { 1721 list_for_each(p, &subs->fmt_list) {
1715 struct audioformat *fp; 1722 struct audioformat *fp;
1716 fp = list_entry(p, struct audioformat, list); 1723 fp = list_entry(p, struct audioformat, list);
1717 if (!hw_check_valid_format(params, fp)) 1724 if (!hw_check_valid_format(subs, params, fp))
1718 continue; 1725 continue;
1719 fbits |= (1ULL << fp->format); 1726 fbits |= (1ULL << fp->format);
1720 } 1727 }
@@ -1732,6 +1739,44 @@ static int hw_rule_format(struct snd_pcm_hw_params *params,
1732 return changed; 1739 return changed;
1733} 1740}
1734 1741
1742static int hw_rule_period_time(struct snd_pcm_hw_params *params,
1743 struct snd_pcm_hw_rule *rule)
1744{
1745 struct snd_usb_substream *subs = rule->private;
1746 struct audioformat *fp;
1747 struct snd_interval *it;
1748 unsigned char min_datainterval;
1749 unsigned int pmin;
1750 int changed;
1751
1752 it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME);
1753 hwc_debug("hw_rule_period_time: (%u,%u)\n", it->min, it->max);
1754 min_datainterval = 0xff;
1755 list_for_each_entry(fp, &subs->fmt_list, list) {
1756 if (!hw_check_valid_format(subs, params, fp))
1757 continue;
1758 min_datainterval = min(min_datainterval, fp->datainterval);
1759 }
1760 if (min_datainterval == 0xff) {
1761 hwc_debug(" --> get emtpy\n");
1762 it->empty = 1;
1763 return -EINVAL;
1764 }
1765 pmin = 125 * (1 << min_datainterval);
1766 changed = 0;
1767 if (it->min < pmin) {
1768 it->min = pmin;
1769 it->openmin = 0;
1770 changed = 1;
1771 }
1772 if (snd_interval_checkempty(it)) {
1773 it->empty = 1;
1774 return -EINVAL;
1775 }
1776 hwc_debug(" --> (%u,%u) (changed = %d)\n", it->min, it->max, changed);
1777 return changed;
1778}
1779
1735/* 1780/*
1736 * If the device supports unusual bit rates, does the request meet these? 1781 * If the device supports unusual bit rates, does the request meet these?
1737 */ 1782 */
@@ -1777,6 +1822,8 @@ static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime,
1777static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substream *subs) 1822static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substream *subs)
1778{ 1823{
1779 struct list_head *p; 1824 struct list_head *p;
1825 unsigned int pt, ptmin;
1826 int param_period_time_if_needed;
1780 int err; 1827 int err;
1781 1828
1782 runtime->hw.formats = subs->formats; 1829 runtime->hw.formats = subs->formats;
@@ -1786,6 +1833,7 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre
1786 runtime->hw.channels_min = 256; 1833 runtime->hw.channels_min = 256;
1787 runtime->hw.channels_max = 0; 1834 runtime->hw.channels_max = 0;
1788 runtime->hw.rates = 0; 1835 runtime->hw.rates = 0;
1836 ptmin = UINT_MAX;
1789 /* check min/max rates and channels */ 1837 /* check min/max rates and channels */
1790 list_for_each(p, &subs->fmt_list) { 1838 list_for_each(p, &subs->fmt_list) {
1791 struct audioformat *fp; 1839 struct audioformat *fp;
@@ -1804,34 +1852,52 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre
1804 runtime->hw.period_bytes_min = runtime->hw.period_bytes_max = 1852 runtime->hw.period_bytes_min = runtime->hw.period_bytes_max =
1805 fp->frame_size; 1853 fp->frame_size;
1806 } 1854 }
1855 pt = 125 * (1 << fp->datainterval);
1856 ptmin = min(ptmin, pt);
1807 } 1857 }
1808 1858
1809 /* set the period time minimum 1ms */ 1859 param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME;
1810 /* FIXME: high-speed mode allows 125us minimum period, but many parts 1860 if (snd_usb_get_speed(subs->dev) != USB_SPEED_HIGH)
1811 * in the current code assume the 1ms period. 1861 /* full speed devices have fixed data packet interval */
1812 */ 1862 ptmin = 1000;
1863 if (ptmin == 1000)
1864 /* if period time doesn't go below 1 ms, no rules needed */
1865 param_period_time_if_needed = -1;
1813 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 1866 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME,
1814 1000, 1867 ptmin, UINT_MAX);
1815 /*(nrpacks * MAX_URBS) * 1000*/ UINT_MAX);
1816 1868
1817 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 1869 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1818 hw_rule_rate, subs, 1870 hw_rule_rate, subs,
1819 SNDRV_PCM_HW_PARAM_FORMAT, 1871 SNDRV_PCM_HW_PARAM_FORMAT,
1820 SNDRV_PCM_HW_PARAM_CHANNELS, 1872 SNDRV_PCM_HW_PARAM_CHANNELS,
1873 param_period_time_if_needed,
1821 -1)) < 0) 1874 -1)) < 0)
1822 return err; 1875 return err;
1823 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 1876 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
1824 hw_rule_channels, subs, 1877 hw_rule_channels, subs,
1825 SNDRV_PCM_HW_PARAM_FORMAT, 1878 SNDRV_PCM_HW_PARAM_FORMAT,
1826 SNDRV_PCM_HW_PARAM_RATE, 1879 SNDRV_PCM_HW_PARAM_RATE,
1880 param_period_time_if_needed,
1827 -1)) < 0) 1881 -1)) < 0)
1828 return err; 1882 return err;
1829 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT, 1883 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
1830 hw_rule_format, subs, 1884 hw_rule_format, subs,
1831 SNDRV_PCM_HW_PARAM_RATE, 1885 SNDRV_PCM_HW_PARAM_RATE,
1832 SNDRV_PCM_HW_PARAM_CHANNELS, 1886 SNDRV_PCM_HW_PARAM_CHANNELS,
1887 param_period_time_if_needed,
1833 -1)) < 0) 1888 -1)) < 0)
1834 return err; 1889 return err;
1890 if (param_period_time_if_needed >= 0) {
1891 err = snd_pcm_hw_rule_add(runtime, 0,
1892 SNDRV_PCM_HW_PARAM_PERIOD_TIME,
1893 hw_rule_period_time, subs,
1894 SNDRV_PCM_HW_PARAM_FORMAT,
1895 SNDRV_PCM_HW_PARAM_CHANNELS,
1896 SNDRV_PCM_HW_PARAM_RATE,
1897 -1);
1898 if (err < 0)
1899 return err;
1900 }
1835 if ((err = snd_usb_pcm_check_knot(runtime, subs)) < 0) 1901 if ((err = snd_usb_pcm_check_knot(runtime, subs)) < 0)
1836 return err; 1902 return err;
1837 return 0; 1903 return 0;