int snd_msnd_DARQ(struct snd_msnd *chip, int bank) { int /*size, n,*/ timeout = 3; u16 wTmp; /* void *DAQD; */ /* Increment the tail and check for queue wrap */ wTmp = readw(chip->DARQ + JQS_wTail) + PCTODSP_OFFSET(DAQDS__size); if (wTmp > readw(chip->DARQ + JQS_wSize)) wTmp = 0; while (wTmp == readw(chip->DARQ + JQS_wHead) && timeout--) udelay(1); if (chip->capturePeriods == 2) { void *pDAQ = chip->mappedbase + DARQ_DATA_BUFF + bank * DAQDS__size + DAQDS_wStart; unsigned short offset = 0x3000 + chip->capturePeriodBytes; if (readw(pDAQ) != PCTODSP_BASED(0x3000)) offset = 0x3000; writew(PCTODSP_BASED(offset), pDAQ); } writew(wTmp, chip->DARQ + JQS_wTail); return 1; }
int snd_msnd_DAPQ(struct snd_msnd *chip, int start) { u16 DAPQ_tail; int protect = start, nbanks = 0; void *DAQD; static int play_banks_submitted; /* unsigned long flags; spin_lock_irqsave(&chip->lock, flags); not necessary */ DAPQ_tail = readw(chip->DAPQ + JQS_wTail); while (DAPQ_tail != readw(chip->DAPQ + JQS_wHead) || start) { int bank_num = DAPQ_tail / PCTODSP_OFFSET(DAQDS__size); if (start) { start = 0; play_banks_submitted = 0; } /* Get our digital audio queue struct */ DAQD = bank_num * DAQDS__size + chip->mappedbase + DAPQ_DATA_BUFF; /* Write size of this bank */ writew(chip->play_period_bytes, DAQD + DAQDS_wSize); if (play_banks_submitted < 3) ++play_banks_submitted; else if (chip->playPeriods == 2) { unsigned short offset = chip->play_period_bytes; if (readw(DAQD + DAQDS_wStart) != PCTODSP_BASED(0x0)) offset = 0; writew(PCTODSP_BASED(offset), DAQD + DAQDS_wStart); } ++nbanks; /* Then advance the tail */ /* if (protect) snd_printd(KERN_INFO "B %X %lX\n", bank_num, xtime.tv_usec); */ DAPQ_tail = (++bank_num % 3) * PCTODSP_OFFSET(DAQDS__size); writew(DAPQ_tail, chip->DAPQ + JQS_wTail); /* Tell the DSP to play the bank */ snd_msnd_send_dsp_cmd(chip, HDEX_PLAY_START); if (protect) if (2 == bank_num) break; } /* if (protect) snd_printd(KERN_INFO "%lX\n", xtime.tv_usec); */ /* spin_unlock_irqrestore(&chip->lock, flags); not necessary */ return nbanks; }
void snd_msnd_init_queue(void *base, int start, int size) { writew(PCTODSP_BASED(start), base + JQS_wStart); writew(PCTODSP_OFFSET(size) - 1, base + JQS_wSize); writew(0, base + JQS_wHead); writew(0, base + JQS_wTail); }
static void snd_msnd_play_reset_queue(struct snd_msnd *chip, unsigned int pcm_periods, unsigned int pcm_count) { int n; void *pDAQ = chip->mappedbase + DAPQ_DATA_BUFF; chip->last_playbank = -1; chip->playLimit = pcm_count * (pcm_periods - 1); chip->playPeriods = pcm_periods; writew(PCTODSP_OFFSET(0 * DAQDS__size), chip->DAPQ + JQS_wHead); writew(PCTODSP_OFFSET(0 * DAQDS__size), chip->DAPQ + JQS_wTail); chip->play_period_bytes = pcm_count; for (n = 0; n < pcm_periods; ++n, pDAQ += DAQDS__size) { writew(PCTODSP_BASED((u32)(pcm_count * n)), pDAQ + DAQDS_wStart); writew(0, pDAQ + DAQDS_wSize); writew(1, pDAQ + DAQDS_wFormat); writew(chip->play_sample_size, pDAQ + DAQDS_wSampleSize); writew(chip->play_channels, pDAQ + DAQDS_wChannels); writew(chip->play_sample_rate, pDAQ + DAQDS_wSampleRate); writew(HIMT_PLAY_DONE * 0x100 + n, pDAQ + DAQDS_wIntMsg); writew(n, pDAQ + DAQDS_wFlags); } }
void msnd_init_queue(unsigned long base, int start, int size) { isa_writew(PCTODSP_BASED(start), base + JQS_wStart); isa_writew(PCTODSP_OFFSET(size) - 1, base + JQS_wSize); isa_writew(0, base + JQS_wHead); isa_writew(0, base + JQS_wTail); }
int snd_msnd_DARQ(struct snd_msnd *chip, int bank) { int /*size, n,*/ timeout = 3; u16 wTmp; /* void *DAQD; */ /* Increment the tail and check for queue wrap */ wTmp = readw(chip->DARQ + JQS_wTail) + PCTODSP_OFFSET(DAQDS__size); if (wTmp > readw(chip->DARQ + JQS_wSize)) wTmp = 0; while (wTmp == readw(chip->DARQ + JQS_wHead) && timeout--) udelay(1); if (chip->capturePeriods == 2) { void *pDAQ = chip->mappedbase + DARQ_DATA_BUFF + bank * DAQDS__size + DAQDS_wStart; unsigned short offset = 0x3000 + chip->capturePeriodBytes; if (readw(pDAQ) != PCTODSP_BASED(0x3000)) offset = 0x3000; writew(PCTODSP_BASED(offset), pDAQ); } writew(wTmp, chip->DARQ + JQS_wTail); #if 0 /* Get our digital audio queue struct */ DAQD = bank * DAQDS__size + chip->mappedbase + DARQ_DATA_BUFF; /* Get length of data */ size = readw(DAQD + DAQDS_wSize); /* Read data from the head (unprotected bank 1 access okay since this is only called inside an interrupt) */ outb(HPBLKSEL_1, chip->io + HP_BLKS); n = msnd_fifo_write(&chip->DARF, (char *)(chip->base + bank * DAR_BUFF_SIZE), size, 0); if (n <= 0) { outb(HPBLKSEL_0, chip->io + HP_BLKS); return n; } outb(HPBLKSEL_0, chip->io + HP_BLKS); #endif return 1; }
static void snd_msnd_capture_reset_queue(struct snd_msnd *chip, unsigned int pcm_periods, unsigned int pcm_count) { int n; void *pDAQ; /* unsigned long flags; */ /* snd_msnd_init_queue(chip->DARQ, DARQ_DATA_BUFF, DARQ_BUFF_SIZE); */ chip->last_recbank = 2; chip->captureLimit = pcm_count * (pcm_periods - 1); chip->capturePeriods = pcm_periods; writew(PCTODSP_OFFSET(0 * DAQDS__size), chip->DARQ + JQS_wHead); writew(PCTODSP_OFFSET(chip->last_recbank * DAQDS__size), chip->DARQ + JQS_wTail); #if 0 /* Critical section: bank 1 access. this is how the OSS driver does it:*/ spin_lock_irqsave(&chip->lock, flags); outb(HPBLKSEL_1, chip->io + HP_BLKS); memset_io(chip->mappedbase, 0, DAR_BUFF_SIZE * 3); outb(HPBLKSEL_0, chip->io + HP_BLKS); spin_unlock_irqrestore(&chip->lock, flags); #endif chip->capturePeriodBytes = pcm_count; snd_printdd("snd_msnd_capture_reset_queue() %i\n", pcm_count); pDAQ = chip->mappedbase + DARQ_DATA_BUFF; for (n = 0; n < pcm_periods; ++n, pDAQ += DAQDS__size) { u32 tmp = pcm_count * n; writew(PCTODSP_BASED(tmp + 0x3000), pDAQ + DAQDS_wStart); writew(pcm_count, pDAQ + DAQDS_wSize); writew(1, pDAQ + DAQDS_wFormat); writew(chip->capture_sample_size, pDAQ + DAQDS_wSampleSize); writew(chip->capture_channels, pDAQ + DAQDS_wChannels); writew(chip->capture_sample_rate, pDAQ + DAQDS_wSampleRate); writew(HIMT_RECORD_DONE * 0x100 + n, pDAQ + DAQDS_wIntMsg); writew(n, pDAQ + DAQDS_wFlags); } }
static void snd_msnd_capture_reset_queue(struct snd_msnd *chip, unsigned int pcm_periods, unsigned int pcm_count) { int n; void *pDAQ; /* unsigned long flags; */ /* snd_msnd_init_queue(chip->DARQ, DARQ_DATA_BUFF, DARQ_BUFF_SIZE); */ chip->last_recbank = 2; chip->captureLimit = pcm_count * (pcm_periods - 1); chip->capturePeriods = pcm_periods; writew(PCTODSP_OFFSET(0 * DAQDS__size), chip->DARQ + JQS_wHead); writew(PCTODSP_OFFSET(chip->last_recbank * DAQDS__size), chip->DARQ + JQS_wTail); chip->capturePeriodBytes = pcm_count; snd_printdd("snd_msnd_capture_reset_queue() %i\n", pcm_count); pDAQ = chip->mappedbase + DARQ_DATA_BUFF; for (n = 0; n < pcm_periods; ++n, pDAQ += DAQDS__size) { u32 tmp = pcm_count * n; writew(PCTODSP_BASED(tmp + 0x3000), pDAQ + DAQDS_wStart); writew(pcm_count, pDAQ + DAQDS_wSize); writew(1, pDAQ + DAQDS_wFormat); writew(chip->capture_sample_size, pDAQ + DAQDS_wSampleSize); writew(chip->capture_channels, pDAQ + DAQDS_wChannels); writew(chip->capture_sample_rate, pDAQ + DAQDS_wSampleRate); writew(HIMT_RECORD_DONE * 0x100 + n, pDAQ + DAQDS_wIntMsg); writew(n, pDAQ + DAQDS_wFlags); } }