Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cf81d6b5 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

Merge branch 'for-next' into for-linus

Merged 4.8 changes.
parents 76df5296 275353bb
Loading
Loading
Loading
Loading
+6 −6
Original line number Original line Diff line number Diff line
@@ -14,7 +14,7 @@ provides a refined estimate with a delay.
event or application query.
event or application query.
The difference (tstamp - trigger_tstamp) defines the elapsed time.
The difference (tstamp - trigger_tstamp) defines the elapsed time.


The ALSA API provides reports two basic pieces of information, avail
The ALSA API provides two basic pieces of information, avail
and delay, which combined with the trigger and current system
and delay, which combined with the trigger and current system
timestamps allow for applications to keep track of the 'fullness' of
timestamps allow for applications to keep track of the 'fullness' of
the ring buffer and the amount of queued samples.
the ring buffer and the amount of queued samples.
@@ -53,21 +53,21 @@ case):
The analog time is taken at the last stage of the playback, as close
The analog time is taken at the last stage of the playback, as close
as possible to the actual transducer
as possible to the actual transducer


The link time is taken at the output of the SOC/chipset as the samples
The link time is taken at the output of the SoC/chipset as the samples
are pushed on a link. The link time can be directly measured if
are pushed on a link. The link time can be directly measured if
supported in hardware by sample counters or wallclocks (e.g. with
supported in hardware by sample counters or wallclocks (e.g. with
HDAudio 24MHz or PTP clock for networked solutions) or indirectly
HDAudio 24MHz or PTP clock for networked solutions) or indirectly
estimated (e.g. with the frame counter in USB).
estimated (e.g. with the frame counter in USB).


The DMA time is measured using counters - typically the least reliable
The DMA time is measured using counters - typically the least reliable
of all measurements due to the bursty natured of DMA transfers.
of all measurements due to the bursty nature of DMA transfers.


The app time corresponds to the time tracked by an application after
The app time corresponds to the time tracked by an application after
writing in the ring buffer.
writing in the ring buffer.


The application can query what the hardware supports, define which
The application can query the hardware capabilities, define which
audio time it wants reported by selecting the relevant settings in
audio time it wants reported by selecting the relevant settings in
audio_tstamp_config fields, get an estimate of the timestamp
audio_tstamp_config fields, thus get an estimate of the timestamp
accuracy. It can also request the delay-to-analog be included in the
accuracy. It can also request the delay-to-analog be included in the
measurement. Direct access to the link time is very interesting on
measurement. Direct access to the link time is very interesting on
platforms that provide an embedded DSP; measuring directly the link
platforms that provide an embedded DSP; measuring directly the link
@@ -169,7 +169,7 @@ playback: systime: 938107562 nsec, audio time 938112708 nsec, systime delta -51
Example 1 shows that the timestamp at the DMA level is close to 1ms
Example 1 shows that the timestamp at the DMA level is close to 1ms
ahead of the actual playback time (as a side time this sort of
ahead of the actual playback time (as a side time this sort of
measurement can help define rewind safeguards). Compensating for the
measurement can help define rewind safeguards). Compensating for the
DMA-link delay in example 2 helps remove the hardware buffering abut
DMA-link delay in example 2 helps remove the hardware buffering but
the information is still very jittery, with up to one sample of
the information is still very jittery, with up to one sample of
error. In example 3 where the timestamps are measured with the link
error. In example 3 where the timestamps are measured with the link
wallclock, the timestamps show a monotonic behavior and a lower
wallclock, the timestamps show a monotonic behavior and a lower
+32 −0
Original line number Original line Diff line number Diff line
@@ -807,6 +807,36 @@ static int snd_ctl_elem_list(struct snd_card *card,
	return 0;
	return 0;
}
}


static bool validate_element_member_dimension(struct snd_ctl_elem_info *info)
{
	unsigned int members;
	unsigned int i;

	if (info->dimen.d[0] == 0)
		return true;

	members = 1;
	for (i = 0; i < ARRAY_SIZE(info->dimen.d); ++i) {
		if (info->dimen.d[i] == 0)
			break;
		members *= info->dimen.d[i];

		/*
		 * info->count should be validated in advance, to guarantee
		 * calculation soundness.
		 */
		if (members > info->count)
			return false;
	}

	for (++i; i < ARRAY_SIZE(info->dimen.d); ++i) {
		if (info->dimen.d[i] > 0)
			return false;
	}

	return members == info->count;
}

static int snd_ctl_elem_info(struct snd_ctl_file *ctl,
static int snd_ctl_elem_info(struct snd_ctl_file *ctl,
			     struct snd_ctl_elem_info *info)
			     struct snd_ctl_elem_info *info)
{
{
@@ -1274,6 +1304,8 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
	if (info->count < 1 ||
	if (info->count < 1 ||
	    info->count > max_value_counts[info->type])
	    info->count > max_value_counts[info->type])
		return -EINVAL;
		return -EINVAL;
	if (!validate_element_member_dimension(info))
		return -EINVAL;
	private_size = value_sizes[info->type] * info->count;
	private_size = value_sizes[info->type] * info->count;


	/*
	/*
+5 −5
Original line number Original line Diff line number Diff line
@@ -70,11 +70,11 @@ struct seq_oss_synth {
static int max_synth_devs;
static int max_synth_devs;
static struct seq_oss_synth *synth_devs[SNDRV_SEQ_OSS_MAX_SYNTH_DEVS];
static struct seq_oss_synth *synth_devs[SNDRV_SEQ_OSS_MAX_SYNTH_DEVS];
static struct seq_oss_synth midi_synth_dev = {
static struct seq_oss_synth midi_synth_dev = {
	-1, /* seq_device */
	.seq_device = -1,
	SYNTH_TYPE_MIDI, /* synth_type */
	.synth_type = SYNTH_TYPE_MIDI,
	0, /* synth_subtype */
	.synth_subtype = 0,
	16, /* nr_voices */
	.nr_voices = 16,
	"MIDI", /* name */
	.name = "MIDI",
};
};


static DEFINE_SPINLOCK(register_lock);
static DEFINE_SPINLOCK(register_lock);
+9 −14
Original line number Original line Diff line number Diff line
@@ -165,7 +165,7 @@ static void snd_seq_timer_interrupt(struct snd_timer_instance *timeri,
	snd_seq_timer_update_tick(&tmr->tick, resolution);
	snd_seq_timer_update_tick(&tmr->tick, resolution);


	/* register actual time of this timer update */
	/* register actual time of this timer update */
	do_gettimeofday(&tmr->last_update);
	ktime_get_ts64(&tmr->last_update);


	spin_unlock_irqrestore(&tmr->lock, flags);
	spin_unlock_irqrestore(&tmr->lock, flags);


@@ -392,7 +392,7 @@ static int seq_timer_start(struct snd_seq_timer *tmr)
		return -EINVAL;
		return -EINVAL;
	snd_timer_start(tmr->timeri, tmr->ticks);
	snd_timer_start(tmr->timeri, tmr->ticks);
	tmr->running = 1;
	tmr->running = 1;
	do_gettimeofday(&tmr->last_update);
	ktime_get_ts64(&tmr->last_update);
	return 0;
	return 0;
}
}


@@ -420,7 +420,7 @@ static int seq_timer_continue(struct snd_seq_timer *tmr)
	}
	}
	snd_timer_start(tmr->timeri, tmr->ticks);
	snd_timer_start(tmr->timeri, tmr->ticks);
	tmr->running = 1;
	tmr->running = 1;
	do_gettimeofday(&tmr->last_update);
	ktime_get_ts64(&tmr->last_update);
	return 0;
	return 0;
}
}


@@ -444,17 +444,12 @@ snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr)
	spin_lock_irqsave(&tmr->lock, flags);
	spin_lock_irqsave(&tmr->lock, flags);
	cur_time = tmr->cur_time;
	cur_time = tmr->cur_time;
	if (tmr->running) { 
	if (tmr->running) { 
		struct timeval tm;
		struct timespec64 tm;
		int usec;

		do_gettimeofday(&tm);
		ktime_get_ts64(&tm);
		usec = (int)(tm.tv_usec - tmr->last_update.tv_usec);
		tm = timespec64_sub(tm, tmr->last_update);
		if (usec < 0) {
		cur_time.tv_nsec = tm.tv_nsec;
			cur_time.tv_nsec += (1000000 + usec) * 1000;
		cur_time.tv_sec = tm.tv_sec;
			cur_time.tv_sec += tm.tv_sec - tmr->last_update.tv_sec - 1;
		} else {
			cur_time.tv_nsec += usec * 1000;
			cur_time.tv_sec += tm.tv_sec - tmr->last_update.tv_sec;
		}
		snd_seq_sanity_real_time(&cur_time);
		snd_seq_sanity_real_time(&cur_time);
	}
	}
	spin_unlock_irqrestore(&tmr->lock, flags);
	spin_unlock_irqrestore(&tmr->lock, flags);
+1 −1
Original line number Original line Diff line number Diff line
@@ -52,7 +52,7 @@ struct snd_seq_timer {
	unsigned int skew;
	unsigned int skew;
	unsigned int skew_base;
	unsigned int skew_base;


	struct timeval 		last_update;	 /* time of last clock update, used for interpolation */
	struct timespec64	last_update;	 /* time of last clock update, used for interpolation */


	spinlock_t lock;
	spinlock_t lock;
};
};
Loading