Ejemplo n.º 1
0
/* write the port and returns the next expire time in ns;
 * called at the trigger-start and in hrtimer callback
 */
static unsigned long pcsp_timer_update(struct hrtimer *handle)
{
	unsigned char timer_cnt, val;
	u64 ns;
	struct snd_pcm_substream *substream;
	struct snd_pcm_runtime *runtime;
	struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer);
	unsigned long flags;

	if (chip->thalf) {
		outb(chip->val61, 0x61);
		chip->thalf = 0;
		if (!atomic_read(&chip->timer_active))
			return 0;
		return chip->ns_rem;
	}

	if (!atomic_read(&chip->timer_active))
		return 0;
	substream = chip->playback_substream;
	if (!substream)
		return 0;

	runtime = substream->runtime;
	/* assume it is mono! */
	val = runtime->dma_area[chip->playback_ptr + chip->fmt_size - 1];
	if (chip->is_signed)
		val ^= 0x80;
	timer_cnt = val * CUR_DIV() / 256;

	if (timer_cnt && chip->enable) {
		spin_lock_irqsave(&i8253_lock, flags);
		if (!nforce_wa) {
			outb_p(chip->val61, 0x61);
			outb_p(timer_cnt, 0x42);
			outb(chip->val61 ^ 1, 0x61);
		} else {
			outb(chip->val61 ^ 2, 0x61);
			chip->thalf = 1;
		}
		spin_unlock_irqrestore(&i8253_lock, flags);
	}

	chip->ns_rem = PCSP_PERIOD_NS();
	ns = (chip->thalf ? PCSP_CALC_NS(timer_cnt) : chip->ns_rem);
	chip->ns_rem -= ns;
	return ns;
}
Ejemplo n.º 2
0
static u64 pcsp_timer_update(struct snd_pcsp *chip)
{
	unsigned char timer_cnt, val;
	u64 ns;
	struct snd_pcm_substream *substream;
	struct snd_pcm_runtime *runtime;
	unsigned long flags;

	if (chip->thalf) {
		outb(chip->val61, 0x61);
		chip->thalf = 0;
		return chip->ns_rem;
	}

	substream = chip->playback_substream;
	if (!substream)
		return 0;

	runtime = substream->runtime;
	
	val = runtime->dma_area[chip->playback_ptr + chip->fmt_size - 1];
	if (chip->is_signed)
		val ^= 0x80;
	timer_cnt = val * CUR_DIV() / 256;

	if (timer_cnt && chip->enable) {
		raw_spin_lock_irqsave(&i8253_lock, flags);
		if (!nforce_wa) {
			outb_p(chip->val61, 0x61);
			outb_p(timer_cnt, 0x42);
			outb(chip->val61 ^ 1, 0x61);
		} else {
			outb(chip->val61 ^ 2, 0x61);
			chip->thalf = 1;
		}
		raw_spin_unlock_irqrestore(&i8253_lock, flags);
	}

	chip->ns_rem = PCSP_PERIOD_NS();
	ns = (chip->thalf ? PCSP_CALC_NS(timer_cnt) : chip->ns_rem);
	chip->ns_rem -= ns;
	return ns;
}