Commit 119925a7 authored by Jaroslav Kysela's avatar Jaroslav Kysela

ALSA CVS update - Takashi Iwai <tiwai@suse.de>

YMFPCI driver
Clemens Ladisch <clemens@ladisch.de>:

- added the support for the timer on ymfpci chips.
parent 95929f63
......@@ -25,6 +25,7 @@
#include "pcm.h"
#include "rawmidi.h"
#include "ac97_codec.h"
#include "timer.h"
#include <linux/gameport.h>
#ifndef PCI_VENDOR_ID_YAMAHA
......@@ -347,6 +348,7 @@ struct _snd_ymfpci {
ac97_t *ac97;
snd_rawmidi_t *rawmidi;
snd_timer_t *timer;
struct pci_dev *pci;
snd_card_t *card;
......@@ -387,6 +389,7 @@ int snd_ymfpci_pcm2(ymfpci_t *chip, int device, snd_pcm_t **rpcm);
int snd_ymfpci_pcm_spdif(ymfpci_t *chip, int device, snd_pcm_t **rpcm);
int snd_ymfpci_pcm_4ch(ymfpci_t *chip, int device, snd_pcm_t **rpcm);
int snd_ymfpci_mixer(ymfpci_t *chip, int rear_switch);
int snd_ymfpci_timer(ymfpci_t *chip, int device);
int snd_ymfpci_voice_alloc(ymfpci_t *chip, ymfpci_voice_type_t type, int pair, ymfpci_voice_t **rvoice);
int snd_ymfpci_voice_free(ymfpci_t *chip, ymfpci_voice_t *pvoice);
......
......@@ -267,6 +267,10 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,
snd_card_free(card);
return err;
}
if ((err = snd_ymfpci_timer(chip, 0)) < 0) {
snd_card_free(card);
return err;
}
if (chip->mpu_res) {
if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_YMFPCI,
mpu_port[dev], 1,
......
......@@ -779,7 +779,8 @@ static irqreturn_t snd_ymfpci_interrupt(int irq, void *dev_id, struct pt_regs *r
status = snd_ymfpci_readw(chip, YDSXGR_INTFLAG);
if (status & 1) {
/* timer handler */
if (chip->timer)
snd_timer_interrupt(chip->timer, chip->timer->sticks);
}
snd_ymfpci_writew(chip, YDSXGR_INTFLAG, status);
......@@ -1702,6 +1703,77 @@ int __devinit snd_ymfpci_mixer(ymfpci_t *chip, int rear_switch)
}
/*
* timer
*/
static int snd_ymfpci_timer_start(snd_timer_t *timer)
{
ymfpci_t *chip;
unsigned long flags;
unsigned int count;
chip = snd_timer_chip(timer);
count = timer->sticks - 1;
if (count == 0) /* minimum time is 20.8 us */
count = 1;
spin_lock_irqsave(&chip->reg_lock, flags);
snd_ymfpci_writew(chip, YDSXGR_TIMERCOUNT, count);
snd_ymfpci_writeb(chip, YDSXGR_TIMERCTRL, 0x03);
spin_unlock_irqrestore(&chip->reg_lock, flags);
return 0;
}
static int snd_ymfpci_timer_stop(snd_timer_t *timer)
{
ymfpci_t *chip;
unsigned long flags;
chip = snd_timer_chip(timer);
spin_lock_irqsave(&chip->reg_lock, flags);
snd_ymfpci_writeb(chip, YDSXGR_TIMERCTRL, 0x00);
spin_unlock_irqrestore(&chip->reg_lock, flags);
return 0;
}
static int snd_ymfpci_timer_precise_resolution(snd_timer_t *timer,
unsigned long *num, unsigned long *den)
{
*num = 1;
*den = 96000;
return 0;
}
static struct _snd_timer_hardware snd_ymfpci_timer_hw = {
.flags = SNDRV_TIMER_HW_AUTO,
.resolution = 10417, /* 1/2fs = 10.41666...us */
.ticks = 65536,
.start = snd_ymfpci_timer_start,
.stop = snd_ymfpci_timer_stop,
.precise_resolution = snd_ymfpci_timer_precise_resolution,
};
int __devinit snd_ymfpci_timer(ymfpci_t *chip, int device)
{
snd_timer_t *timer = NULL;
snd_timer_id_t tid;
int err;
tid.dev_class = SNDRV_TIMER_CLASS_CARD;
tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
tid.card = chip->card->number;
tid.device = device;
tid.subdevice = 0;
if ((err = snd_timer_new(chip->card, "YMFPCI", &tid, &timer)) >= 0) {
strcpy(timer->name, "YMFPCI timer");
timer->private_data = chip;
timer->hw = snd_ymfpci_timer_hw;
}
chip->timer = timer;
return err;
}
/*
* proc interface
*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment