Commit bc5304b6 authored by Takashi Iwai's avatar Takashi Iwai

ALSA: ctxfi - Native timer support for emu20k2

Added the native timer support for emu20k2, which gives much more
accurate update timing than the system timer.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 6847e154
...@@ -11,9 +11,12 @@ ...@@ -11,9 +11,12 @@
/* Timer Registers */ /* Timer Registers */
#define TIMER_TIMR 0x1B7004 #define WC 0x1b7000
#define INTERRUPT_GIP 0x1B7010 #define TIMR 0x1b7004
#define INTERRUPT_GIE 0x1B7014 # define TIMR_IE (1<<15)
# define TIMR_IP (1<<14)
#define GIP 0x1b7010
#define GIE 0x1b7014
/* I2C Registers */ /* I2C Registers */
#define I2C_IF_ADDRESS 0x1B9000 #define I2C_IF_ADDRESS 0x1B9000
......
...@@ -1112,6 +1112,26 @@ static int daio_mgr_put_ctrl_blk(void *blk) ...@@ -1112,6 +1112,26 @@ static int daio_mgr_put_ctrl_blk(void *blk)
return 0; return 0;
} }
/* Timer interrupt */
static int set_timer_irq(struct hw *hw, int enable)
{
hw_write_20kx(hw, GIE, enable ? IT_INT : 0);
return 0;
}
static int set_timer_tick(struct hw *hw, unsigned int ticks)
{
if (ticks)
ticks |= TIMR_IE | TIMR_IP;
hw_write_20kx(hw, TIMR, ticks);
return 0;
}
static unsigned int get_wc(struct hw *hw)
{
return hw_read_20kx(hw, WC);
}
/* Card hardware initialization block */ /* Card hardware initialization block */
struct dac_conf { struct dac_conf {
unsigned int msr; /* master sample rate in rsrs */ unsigned int msr; /* master sample rate in rsrs */
...@@ -1841,6 +1861,22 @@ static int hw_have_digit_io_switch(struct hw *hw) ...@@ -1841,6 +1861,22 @@ static int hw_have_digit_io_switch(struct hw *hw)
return 0; return 0;
} }
static irqreturn_t ct_20k2_interrupt(int irq, void *dev_id)
{
struct hw *hw = dev_id;
unsigned int status;
status = hw_read_20kx(hw, GIP);
if (!status)
return IRQ_NONE;
if (hw->irq_callback)
hw->irq_callback(hw->irq_callback_data, status);
hw_write_20kx(hw, GIP, status);
return IRQ_HANDLED;
}
static int hw_card_start(struct hw *hw) static int hw_card_start(struct hw *hw)
{ {
int err = 0; int err = 0;
...@@ -1879,12 +1915,15 @@ static int hw_card_start(struct hw *hw) ...@@ -1879,12 +1915,15 @@ static int hw_card_start(struct hw *hw)
set_field(&gctl, GCTL_UAA, 0); set_field(&gctl, GCTL_UAA, 0);
hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl); hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl);
/*if ((err = request_irq(pci->irq, ct_atc_interrupt, IRQF_SHARED, if (hw->irq < 0) {
atc->chip_details->nm_card, hw))) { err = request_irq(pci->irq, ct_20k2_interrupt, IRQF_SHARED,
goto error3; "ctxfi", hw);
if (err < 0) {
printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq);
goto error2;
}
hw->irq = pci->irq;
} }
hw->irq = pci->irq;
*/
pci_set_master(pci); pci_set_master(pci);
...@@ -1972,7 +2011,7 @@ static int hw_card_init(struct hw *hw, struct card_conf *info) ...@@ -1972,7 +2011,7 @@ static int hw_card_init(struct hw *hw, struct card_conf *info)
hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl); hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl);
/* Reset all global pending interrupts */ /* Reset all global pending interrupts */
hw_write_20kx(hw, INTERRUPT_GIE, 0); hw_write_20kx(hw, GIE, 0);
/* Reset all SRC pending interrupts */ /* Reset all SRC pending interrupts */
hw_write_20kx(hw, SRC_IP, 0); hw_write_20kx(hw, SRC_IP, 0);
...@@ -2149,6 +2188,10 @@ static struct hw ct20k2_preset __devinitdata = { ...@@ -2149,6 +2188,10 @@ static struct hw ct20k2_preset __devinitdata = {
.daio_mgr_set_imapnxt = daio_mgr_set_imapnxt, .daio_mgr_set_imapnxt = daio_mgr_set_imapnxt,
.daio_mgr_set_imapaddr = daio_mgr_set_imapaddr, .daio_mgr_set_imapaddr = daio_mgr_set_imapaddr,
.daio_mgr_commit_write = daio_mgr_commit_write, .daio_mgr_commit_write = daio_mgr_commit_write,
.set_timer_irq = set_timer_irq,
.set_timer_tick = set_timer_tick,
.get_wc = get_wc,
}; };
int __devinit create_20k2_hw_obj(struct hw **rhw) int __devinit create_20k2_hw_obj(struct hw **rhw)
......
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