/* timer interrupt handler check the current position and update the period if necessary.  */
static void emu8k_pcm_timer_func(unsigned long data)
/* timer interrupt handler check the current position and update the period if necessary.  */
static void emu8k_pcm_timer_func(unsigned long data)
{
	struct snd_emu8k_pcm *rec = (struct snd_emu8k_pcm *)data;
	int ptr, delta;
	spin_lock(&rec->timer_lock);
	ptr = emu8k_get_curpos(rec, 0);
	if (ptr < rec->last_ptr)
		delta = ptr + rec->buf_size - rec->last_ptr;
	else
		delta = ptr - rec->last_ptr;
	rec->period_pos += delta;
	rec->last_ptr = ptr;
	rec->timer.expires = jiffies + 1;
	add_timer(&rec->timer);
	if (rec->period_pos >= (int)rec->period_size) {
		rec->period_pos %= rec->period_size;
		spin_unlock(&rec->timer_lock);
		snd_pcm_period_elapsed(rec->substream);
		return;
	}
	spin_unlock(&rec->timer_lock);
}