diff options
Diffstat (limited to 'sound')
110 files changed, 2222 insertions, 746 deletions
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index ec9e7866177f..446c00bd908b 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -1015,6 +1015,60 @@ int snd_interval_list(struct snd_interval *i, unsigned int count, EXPORT_SYMBOL(snd_interval_list); +/** + * snd_interval_ranges - refine the interval value from the list of ranges + * @i: the interval value to refine + * @count: the number of elements in the list of ranges + * @ranges: the ranges list + * @mask: the bit-mask to evaluate + * + * Refines the interval value from the list of ranges. + * When mask is non-zero, only the elements corresponding to bit 1 are + * evaluated. + * + * Return: Positive if the value is changed, zero if it's not changed, or a + * negative error code. + */ +int snd_interval_ranges(struct snd_interval *i, unsigned int count, + const struct snd_interval *ranges, unsigned int mask) +{ + unsigned int k; + struct snd_interval range_union; + struct snd_interval range; + + if (!count) { + snd_interval_none(i); + return -EINVAL; + } + snd_interval_any(&range_union); + range_union.min = UINT_MAX; + range_union.max = 0; + for (k = 0; k < count; k++) { + if (mask && !(mask & (1 << k))) + continue; + snd_interval_copy(&range, &ranges[k]); + if (snd_interval_refine(&range, i) < 0) + continue; + if (snd_interval_empty(&range)) + continue; + + if (range.min < range_union.min) { + range_union.min = range.min; + range_union.openmin = 1; + } + if (range.min == range_union.min && !range.openmin) + range_union.openmin = 0; + if (range.max > range_union.max) { + range_union.max = range.max; + range_union.openmax = 1; + } + if (range.max == range_union.max && !range.openmax) + range_union.openmax = 0; + } + return snd_interval_refine(i, &range_union); +} +EXPORT_SYMBOL(snd_interval_ranges); + static int snd_interval_step(struct snd_interval *i, unsigned int step) { unsigned int n; @@ -1221,6 +1275,37 @@ int snd_pcm_hw_constraint_list(struct snd_pcm_runtime *runtime, EXPORT_SYMBOL(snd_pcm_hw_constraint_list); +static int snd_pcm_hw_rule_ranges(struct snd_pcm_hw_params *params, + struct snd_pcm_hw_rule *rule) +{ + struct snd_pcm_hw_constraint_ranges *r = rule->private; + return snd_interval_ranges(hw_param_interval(params, rule->var), + r->count, r->ranges, r->mask); +} + + +/** + * snd_pcm_hw_constraint_ranges - apply list of range constraints to a parameter + * @runtime: PCM runtime instance + * @cond: condition bits + * @var: hw_params variable to apply the list of range constraints + * @r: ranges + * + * Apply the list of range constraints to an interval parameter. + * + * Return: Zero if successful, or a negative error code on failure. + */ +int snd_pcm_hw_constraint_ranges(struct snd_pcm_runtime *runtime, + unsigned int cond, + snd_pcm_hw_param_t var, + const struct snd_pcm_hw_constraint_ranges *r) +{ + return snd_pcm_hw_rule_add(runtime, cond, var, + snd_pcm_hw_rule_ranges, (void *)r, + var, -1); +} +EXPORT_SYMBOL(snd_pcm_hw_constraint_ranges); + static int snd_pcm_hw_rule_ratnums(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) { diff --git a/sound/core/seq/seq_dummy.c b/sound/core/seq/seq_dummy.c index ec667f158f19..5d905d90d504 100644 --- a/sound/core/seq/seq_dummy.c +++ b/sound/core/seq/seq_dummy.c @@ -82,36 +82,6 @@ struct snd_seq_dummy_port { static int my_client = -1; /* - * unuse callback - send ALL_SOUNDS_OFF and RESET_CONTROLLERS events - * to subscribers. - * Note: this callback is called only after all subscribers are removed. - */ -static int -dummy_unuse(void *private_data, struct snd_seq_port_subscribe *info) -{ - struct snd_seq_dummy_port *p; - int i; - struct snd_seq_event ev; - - p = private_data; - memset(&ev, 0, sizeof(ev)); - if (p->duplex) - ev.source.port = p->connect; - else - ev.source.port = p->port; - ev.dest.client = SNDRV_SEQ_ADDRESS_SUBSCRIBERS; - ev.type = SNDRV_SEQ_EVENT_CONTROLLER; - for (i = 0; i < 16; i++) { - ev.data.control.channel = i; - ev.data.control.param = MIDI_CTL_ALL_SOUNDS_OFF; - snd_seq_kernel_client_dispatch(p->client, &ev, 0, 0); - ev.data.control.param = MIDI_CTL_RESET_CONTROLLERS; - snd_seq_kernel_client_dispatch(p->client, &ev, 0, 0); - } - return 0; -} - -/* * event input callback - just redirect events to subscribers */ static int @@ -175,7 +145,6 @@ create_port(int idx, int type) | SNDRV_SEQ_PORT_TYPE_PORT; memset(&pcb, 0, sizeof(pcb)); pcb.owner = THIS_MODULE; - pcb.unuse = dummy_unuse; pcb.event_input = dummy_input; pcb.private_free = dummy_free; pcb.private_data = rec; diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c index 3badc70124ab..0d580186ef1a 100644 --- a/sound/firewire/amdtp.c +++ b/sound/firewire/amdtp.c @@ -21,7 +21,19 @@ #define CYCLES_PER_SECOND 8000 #define TICKS_PER_SECOND (TICKS_PER_CYCLE * CYCLES_PER_SECOND) -#define TRANSFER_DELAY_TICKS 0x2e00 /* 479.17 µs */ +/* + * Nominally 3125 bytes/second, but the MIDI port's clock might be + * 1% too slow, and the bus clock 100 ppm too fast. + */ +#define MIDI_BYTES_PER_SECOND 3093 + +/* + * Several devices look only at the first eight data blocks. + * In any case, this is more than enough for the MIDI data rate. + */ +#define MAX_MIDI_RX_BLOCKS 8 + +#define TRANSFER_DELAY_TICKS 0x2e00 /* 479.17 µs */ /* isochronous header parameters */ #define ISO_DATA_LENGTH_SHIFT 16 @@ -78,8 +90,6 @@ int amdtp_stream_init(struct amdtp_stream *s, struct |