linux/sound/pci/emu10k1/timer.c
<<
>>
Prefs
   1/*
   2 *  Copyright (c) by Lee Revell <rlrevell@joe-job.com>
   3 *                   Clemens Ladisch <clemens@ladisch.de>
   4 *  Routines for control of EMU10K1 chips
   5 *
   6 *  BUGS:
   7 *    --
   8 *
   9 *  TODO:
  10 *    --
  11 *
  12 *   This program is free software; you can redistribute it and/or modify
  13 *   it under the terms of the GNU General Public License as published by
  14 *   the Free Software Foundation; either version 2 of the License, or
  15 *   (at your option) any later version.
  16 *
  17 *   This program is distributed in the hope that it will be useful,
  18 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  19 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20 *   GNU General Public License for more details.
  21 *
  22 *   You should have received a copy of the GNU General Public License
  23 *   along with this program; if not, write to the Free Software
  24 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  25 *
  26 */
  27
  28#include <linux/time.h>
  29#include <sound/core.h>
  30#include <sound/emu10k1.h>
  31
  32static int snd_emu10k1_timer_start(struct snd_timer *timer)
  33{
  34        struct snd_emu10k1 *emu;
  35        unsigned long flags;
  36        unsigned int delay;
  37
  38        emu = snd_timer_chip(timer);
  39        delay = timer->sticks - 1;
  40        if (delay < 5 ) /* minimum time is 5 ticks */
  41                delay = 5;
  42        spin_lock_irqsave(&emu->reg_lock, flags);
  43        snd_emu10k1_intr_enable(emu, INTE_INTERVALTIMERENB);
  44        outw(delay & TIMER_RATE_MASK, emu->port + TIMER);
  45        spin_unlock_irqrestore(&emu->reg_lock, flags);
  46        return 0;
  47}
  48
  49static int snd_emu10k1_timer_stop(struct snd_timer *timer)
  50{
  51        struct snd_emu10k1 *emu;
  52        unsigned long flags;
  53
  54        emu = snd_timer_chip(timer);
  55        spin_lock_irqsave(&emu->reg_lock, flags);
  56        snd_emu10k1_intr_disable(emu, INTE_INTERVALTIMERENB);
  57        spin_unlock_irqrestore(&emu->reg_lock, flags);
  58        return 0;
  59}
  60
  61static int snd_emu10k1_timer_precise_resolution(struct snd_timer *timer,
  62                                               unsigned long *num, unsigned long *den)
  63{
  64        *num = 1;
  65        *den = 48000;
  66        return 0;
  67}
  68
  69static struct snd_timer_hardware snd_emu10k1_timer_hw = {
  70        .flags = SNDRV_TIMER_HW_AUTO,
  71        .resolution = 20833, /* 1 sample @ 48KHZ = 20.833...us */
  72        .ticks = 1024,
  73        .start = snd_emu10k1_timer_start,
  74        .stop = snd_emu10k1_timer_stop,
  75        .precise_resolution = snd_emu10k1_timer_precise_resolution,
  76};
  77
  78int __devinit snd_emu10k1_timer(struct snd_emu10k1 *emu, int device)
  79{
  80        struct snd_timer *timer = NULL;
  81        struct snd_timer_id tid;
  82        int err;
  83
  84        tid.dev_class = SNDRV_TIMER_CLASS_CARD;
  85        tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
  86        tid.card = emu->card->number;
  87        tid.device = device;
  88        tid.subdevice = 0;
  89        if ((err = snd_timer_new(emu->card, "EMU10K1", &tid, &timer)) >= 0) {
  90                strcpy(timer->name, "EMU10K1 timer");
  91                timer->private_data = emu;
  92                timer->hw = snd_emu10k1_timer_hw;
  93        }
  94        emu->timer = timer;
  95        return err;
  96}
  97