cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

timer.c (2065B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *  Copyright (c) by Lee Revell <rlrevell@joe-job.com>
      4 *                   Clemens Ladisch <clemens@ladisch.de>
      5 *  Routines for control of EMU10K1 chips
      6 *
      7 *  BUGS:
      8 *    --
      9 *
     10 *  TODO:
     11 *    --
     12 */
     13
     14#include <linux/time.h>
     15#include <sound/core.h>
     16#include <sound/emu10k1.h>
     17
     18static int snd_emu10k1_timer_start(struct snd_timer *timer)
     19{
     20	struct snd_emu10k1 *emu;
     21	unsigned long flags;
     22	unsigned int delay;
     23
     24	emu = snd_timer_chip(timer);
     25	delay = timer->sticks - 1;
     26	if (delay < 5 ) /* minimum time is 5 ticks */
     27		delay = 5;
     28	spin_lock_irqsave(&emu->reg_lock, flags);
     29	snd_emu10k1_intr_enable(emu, INTE_INTERVALTIMERENB);
     30	outw(delay & TIMER_RATE_MASK, emu->port + TIMER);
     31	spin_unlock_irqrestore(&emu->reg_lock, flags);
     32	return 0;
     33}
     34
     35static int snd_emu10k1_timer_stop(struct snd_timer *timer)
     36{
     37	struct snd_emu10k1 *emu;
     38	unsigned long flags;
     39
     40	emu = snd_timer_chip(timer);
     41	spin_lock_irqsave(&emu->reg_lock, flags);
     42	snd_emu10k1_intr_disable(emu, INTE_INTERVALTIMERENB);
     43	spin_unlock_irqrestore(&emu->reg_lock, flags);
     44	return 0;
     45}
     46
     47static int snd_emu10k1_timer_precise_resolution(struct snd_timer *timer,
     48					       unsigned long *num, unsigned long *den)
     49{
     50	*num = 1;
     51	*den = 48000;
     52	return 0;
     53}
     54
     55static const struct snd_timer_hardware snd_emu10k1_timer_hw = {
     56	.flags = SNDRV_TIMER_HW_AUTO,
     57	.resolution = 20833, /* 1 sample @ 48KHZ = 20.833...us */
     58	.ticks = 1024,
     59	.start = snd_emu10k1_timer_start,
     60	.stop = snd_emu10k1_timer_stop,
     61	.precise_resolution = snd_emu10k1_timer_precise_resolution,
     62};
     63
     64int snd_emu10k1_timer(struct snd_emu10k1 *emu, int device)
     65{
     66	struct snd_timer *timer = NULL;
     67	struct snd_timer_id tid;
     68	int err;
     69
     70	tid.dev_class = SNDRV_TIMER_CLASS_CARD;
     71	tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
     72	tid.card = emu->card->number;
     73	tid.device = device;
     74	tid.subdevice = 0;
     75	err = snd_timer_new(emu->card, "EMU10K1", &tid, &timer);
     76	if (err >= 0) {
     77		strcpy(timer->name, "EMU10K1 timer");
     78		timer->private_data = emu;
     79		timer->hw = snd_emu10k1_timer_hw;
     80	}
     81	emu->timer = timer;
     82	return err;
     83}