Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bc5304b6 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

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
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -11,9 +11,12 @@


/* Timer Registers */
#define TIMER_TIMR          0x1B7004
#define INTERRUPT_GIP       0x1B7010
#define INTERRUPT_GIE       0x1B7014
#define WC		0x1b7000
#define TIMR		0x1b7004
# define	TIMR_IE		(1<<15)
# define	TIMR_IP		(1<<14)
#define GIP		0x1b7010
#define GIE		0x1b7014

/* I2C Registers */
#define I2C_IF_ADDRESS   0x1B9000
+49 −6
Original line number Diff line number Diff line
@@ -1112,6 +1112,26 @@ static int daio_mgr_put_ctrl_blk(void *blk)
	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 */
struct dac_conf {
	unsigned int msr; /* master sample rate in rsrs */
@@ -1841,6 +1861,22 @@ static int hw_have_digit_io_switch(struct hw *hw)
	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)
{
	int err = 0;
@@ -1879,12 +1915,15 @@ static int hw_card_start(struct hw *hw)
	set_field(&gctl, GCTL_UAA, 0);
	hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl);

	/*if ((err = request_irq(pci->irq, ct_atc_interrupt, IRQF_SHARED,
				atc->chip_details->nm_card, hw))) {
		goto error3;
	if (hw->irq < 0) {
		err = request_irq(pci->irq, ct_20k2_interrupt, IRQF_SHARED,
				  "ctxfi", hw);
		if (err < 0) {
			printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq);
			goto error2;
		}
		hw->irq = pci->irq;
	*/
	}

	pci_set_master(pci);

@@ -1972,7 +2011,7 @@ static int hw_card_init(struct hw *hw, struct card_conf *info)
	hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl);

	/* Reset all global pending interrupts */
	hw_write_20kx(hw, INTERRUPT_GIE, 0);
	hw_write_20kx(hw, GIE, 0);
	/* Reset all SRC pending interrupts */
	hw_write_20kx(hw, SRC_IP, 0);

@@ -2149,6 +2188,10 @@ static struct hw ct20k2_preset __devinitdata = {
	.daio_mgr_set_imapnxt = daio_mgr_set_imapnxt,
	.daio_mgr_set_imapaddr = daio_mgr_set_imapaddr,
	.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)