254 |
DEFINE_REGSET(AL_PO, 0x50); /* Ali PCM out */ |
DEFINE_REGSET(AL_PO, 0x50); /* Ali PCM out */ |
255 |
DEFINE_REGSET(AL_MC, 0x60); /* Ali Mic in */ |
DEFINE_REGSET(AL_MC, 0x60); /* Ali Mic in */ |
256 |
DEFINE_REGSET(AL_CDC_SPO, 0x70); /* Ali Codec SPDIF out */ |
DEFINE_REGSET(AL_CDC_SPO, 0x70); /* Ali Codec SPDIF out */ |
257 |
|
DEFINE_REGSET(AL_CENTER, 0x80); /* Ali center out */ |
258 |
|
DEFINE_REGSET(AL_LFE, 0x90); /* Ali center out */ |
259 |
DEFINE_REGSET(AL_CLR_SPI, 0xa0); /* Ali Controller SPDIF in */ |
DEFINE_REGSET(AL_CLR_SPI, 0xa0); /* Ali Controller SPDIF in */ |
260 |
DEFINE_REGSET(AL_CLR_SPO, 0xb0); /* Ali Controller SPDIF out */ |
DEFINE_REGSET(AL_CLR_SPO, 0xb0); /* Ali Controller SPDIF out */ |
261 |
|
DEFINE_REGSET(AL_I2S, 0xc0); /* Ali I2S in */ |
262 |
|
DEFINE_REGSET(AL_PI2, 0xd0); /* Ali PCM2 in */ |
263 |
|
DEFINE_REGSET(AL_MC2, 0xe0); /* Ali Mic2 in */ |
264 |
|
|
265 |
enum { |
enum { |
266 |
ICH_REG_ALI_SCR = 0x00, /* System Control Register */ |
ICH_REG_ALI_SCR = 0x00, /* System Control Register */ |
280 |
ICH_REG_ALI_RTSR = 0x34, /* Receive Tag Slot Register */ |
ICH_REG_ALI_RTSR = 0x34, /* Receive Tag Slot Register */ |
281 |
ICH_REG_ALI_CSPSR = 0x38, /* Command/Status Port Status Register */ |
ICH_REG_ALI_CSPSR = 0x38, /* Command/Status Port Status Register */ |
282 |
ICH_REG_ALI_CAS = 0x3c, /* Codec Write Semaphore Register */ |
ICH_REG_ALI_CAS = 0x3c, /* Codec Write Semaphore Register */ |
283 |
|
ICH_REG_ALI_HWVOL = 0xf0, /* hardware volume control/status */ |
284 |
|
ICH_REG_ALI_I2SCR = 0xf4, /* I2S control/status */ |
285 |
ICH_REG_ALI_SPDIFCSR = 0xf8, /* spdif channel status register */ |
ICH_REG_ALI_SPDIFCSR = 0xf8, /* spdif channel status register */ |
286 |
ICH_REG_ALI_SPDIFICS = 0xfc /* spdif interface control/status */ |
ICH_REG_ALI_SPDIFICS = 0xfc, /* spdif interface control/status */ |
287 |
}; |
}; |
288 |
|
|
289 |
#define ALI_CAS_SEM_BUSY 0x80000000 |
#define ALI_CAS_SEM_BUSY 0x80000000 |
290 |
#define ALI_CSPSR_CODEC_READY 0x08 |
#define ALI_CPR_ADDR_SECONDARY 0x100 |
291 |
#define ALI_CPR_ADDR_READ 0x80 |
#define ALI_CPR_ADDR_READ 0x80 |
292 |
|
#define ALI_CSPSR_CODEC_READY 0x08 |
293 |
#define ALI_CSPSR_READ_OK 0x02 |
#define ALI_CSPSR_READ_OK 0x02 |
294 |
#define ALI_CSPSR_WRITE_OK 0x01 |
#define ALI_CSPSR_WRITE_OK 0x01 |
295 |
|
|
296 |
/* interrupts for the whole chip by interrupt status register finish */ |
/* interrupts for the whole chip by interrupt status register finish */ |
297 |
|
|
298 |
|
#define ALI_INT_MICIN2 (1<<26) |
299 |
|
#define ALI_INT_PCMIN2 (1<<25) |
300 |
|
#define ALI_INT_I2SIN (1<<24) |
301 |
#define ALI_INT_SPDIFOUT (1<<23) /* controller spdif out INTERRUPT */ |
#define ALI_INT_SPDIFOUT (1<<23) /* controller spdif out INTERRUPT */ |
302 |
#define ALI_INT_SPDIFIN (1<<22) |
#define ALI_INT_SPDIFIN (1<<22) |
303 |
|
#define ALI_INT_LFEOUT (1<<21) |
304 |
|
#define ALI_INT_CENTEROUT (1<<20) |
305 |
#define ALI_INT_CODECSPDIFOUT (1<<19) |
#define ALI_INT_CODECSPDIFOUT (1<<19) |
306 |
#define ALI_INT_MICIN (1<<18) |
#define ALI_INT_MICIN (1<<18) |
307 |
#define ALI_INT_PCMOUT (1<<17) |
#define ALI_INT_PCMOUT (1<<17) |
308 |
#define ALI_INT_PCMIN (1<<16) |
#define ALI_INT_PCMIN (1<<16) |
309 |
#define ALI_INT_CPRAIS (1<<7) |
#define ALI_INT_CPRAIS (1<<7) /* command port available */ |
310 |
#define ALI_INT_SPRAIS (1<<5) |
#define ALI_INT_SPRAIS (1<<5) /* status port available */ |
311 |
#define ALI_INT_GPIO (1<<1) |
#define ALI_INT_GPIO (1<<1) |
312 |
#define ALI_INT_MASK (ALI_INT_SPDIFOUT|ALI_INT_CODECSPDIFOUT|ALI_INT_MICIN|ALI_INT_PCMOUT|ALI_INT_PCMIN) |
#define ALI_INT_MASK (ALI_INT_SPDIFOUT|ALI_INT_CODECSPDIFOUT|ALI_INT_MICIN|ALI_INT_PCMOUT|ALI_INT_PCMIN) |
313 |
|
|
314 |
#define ALI_PCM_CH4 0x100 |
#define ICH_ALI_SC_RESET (1<<31) /* master reset */ |
315 |
#define ALI_PCM_CH6 0x200 |
#define ICH_ALI_SC_AC97_DBL (1<<30) |
316 |
#define ALI_PCM_MASK (ALI_PCM_CH4 | ALI_PCM_CH6) |
#define ICH_ALI_SC_CODEC_SPDF (3<<20) /* 1=7/8, 2=6/9, 3=10/11 */ |
317 |
|
#define ICH_ALI_SC_IN_BITS (3<<18) |
318 |
|
#define ICH_ALI_SC_OUT_BITS (3<<16) |
319 |
|
#define ICH_ALI_SC_6CH_CFG (3<<14) |
320 |
|
#define ICH_ALI_SC_PCM_4 (1<<8) |
321 |
|
#define ICH_ALI_SC_PCM_6 (2<<8) |
322 |
|
#define ICH_ALI_SC_PCM_246_MASK (3<<8) |
323 |
|
|
324 |
|
#define ICH_ALI_SS_SEC_ID (3<<5) |
325 |
|
#define ICH_ALI_SS_PRI_ID (3<<3) |
326 |
|
|
327 |
|
#define ICH_ALI_IF_AC97SP (1<<21) |
328 |
|
#define ICH_ALI_IF_MC (1<<20) |
329 |
|
#define ICH_ALI_IF_PI (1<<19) |
330 |
|
#define ICH_ALI_IF_MC2 (1<<18) |
331 |
|
#define ICH_ALI_IF_PI2 (1<<17) |
332 |
|
#define ICH_ALI_IF_LINE_SRC (1<<15) /* 0/1 = slot 3/6 */ |
333 |
|
#define ICH_ALI_IF_MIC_SRC (1<<14) /* 0/1 = slot 3/6 */ |
334 |
|
#define ICH_ALI_IF_SPDF_SRC (3<<12) /* 00 = PCM, 01 = AC97-in, 10 = spdif-in, 11 = i2s */ |
335 |
|
#define ICH_ALI_IF_AC97_OUT (3<<8) /* 00 = PCM, 10 = spdif-in, 11 = i2s */ |
336 |
|
#define ICH_ALI_IF_PO_SPDF (1<<3) |
337 |
|
#define ICH_ALI_IF_PO (1<<1) |
338 |
|
|
339 |
/* |
/* |
340 |
* |
* |
370 |
ac97_t *ac97; |
ac97_t *ac97; |
371 |
unsigned short ac97_rate_regs[3]; |
unsigned short ac97_rate_regs[3]; |
372 |
int ac97_rates_idx; |
int ac97_rates_idx; |
|
#ifdef CONFIG_PM |
|
|
unsigned char civ_saved; |
|
|
unsigned char piv_saved; |
|
|
unsigned short picb_saved; |
|
|
#endif |
|
373 |
} ichdev_t; |
} ichdev_t; |
374 |
|
|
375 |
typedef struct _snd_intel8x0 intel8x0_t; |
typedef struct _snd_intel8x0 intel8x0_t; |
632 |
int time = 100; |
int time = 100; |
633 |
while (time-- && (igetdword(chip, ICHREG(ALI_CAS)) & ALI_CAS_SEM_BUSY)) |
while (time-- && (igetdword(chip, ICHREG(ALI_CAS)) & ALI_CAS_SEM_BUSY)) |
634 |
udelay(1); |
udelay(1); |
635 |
|
if (! time) |
636 |
|
snd_printk(KERN_WARNING "ali_codec_semaphore timeout\n"); |
637 |
return snd_intel8x0_ali_codec_ready(chip, ALI_CSPSR_CODEC_READY); |
return snd_intel8x0_ali_codec_ready(chip, ALI_CSPSR_CODEC_READY); |
638 |
} |
} |
639 |
|
|
640 |
static unsigned short snd_intel8x0_ali_codec_read(ac97_t *ac97, unsigned short reg) |
static unsigned short snd_intel8x0_ali_codec_read(ac97_t *ac97, unsigned short reg) |
641 |
{ |
{ |
642 |
intel8x0_t *chip = snd_magic_cast(intel8x0_t, ac97->private_data, return ~0); |
intel8x0_t *chip = snd_magic_cast(intel8x0_t, ac97->private_data, return ~0); |
643 |
unsigned short data, reg2; |
unsigned short data = 0xffff; |
644 |
|
|
645 |
spin_lock(&chip->ac97_lock); |
spin_lock(&chip->ac97_lock); |
646 |
if (snd_intel8x0_ali_codec_semaphore(chip)) |
if (snd_intel8x0_ali_codec_semaphore(chip)) |
647 |
goto __err; |
goto __err; |
648 |
iputword(chip, ICHREG(ALI_CPR_ADDR), reg | ALI_CPR_ADDR_READ); |
reg |= ALI_CPR_ADDR_READ; |
649 |
|
if (ac97->num) |
650 |
|
reg |= ALI_CPR_ADDR_SECONDARY; |
651 |
|
iputword(chip, ICHREG(ALI_CPR_ADDR), reg); |
652 |
if (snd_intel8x0_ali_codec_ready(chip, ALI_CSPSR_READ_OK)) |
if (snd_intel8x0_ali_codec_ready(chip, ALI_CSPSR_READ_OK)) |
653 |
goto __err; |
goto __err; |
654 |
data = igetword(chip, ICHREG(ALI_SPR)); |
data = igetword(chip, ICHREG(ALI_SPR)); |
|
reg2 = igetword(chip, ICHREG(ALI_SPR_ADDR)); |
|
|
if (reg != reg2) { |
|
|
snd_printd(KERN_WARNING "intel8x0: AC97 read not completed? 0x%x != 0x%x\n", reg, reg2); |
|
|
// goto __err; |
|
|
} |
|
|
spin_unlock(&chip->ac97_lock); |
|
|
return data; |
|
655 |
__err: |
__err: |
656 |
spin_unlock(&chip->ac97_lock); |
spin_unlock(&chip->ac97_lock); |
657 |
return 0xffff; |
return data; |
658 |
} |
} |
659 |
|
|
660 |
static void snd_intel8x0_ali_codec_write(ac97_t *ac97, unsigned short reg, unsigned short val) |
static void snd_intel8x0_ali_codec_write(ac97_t *ac97, unsigned short reg, unsigned short val) |
667 |
return; |
return; |
668 |
} |
} |
669 |
iputword(chip, ICHREG(ALI_CPR), val); |
iputword(chip, ICHREG(ALI_CPR), val); |
670 |
iputbyte(chip, ICHREG(ALI_CPR_ADDR), reg); |
if (ac97->num) |
671 |
|
reg |= ALI_CPR_ADDR_SECONDARY; |
672 |
|
iputword(chip, ICHREG(ALI_CPR_ADDR), reg); |
673 |
snd_intel8x0_ali_codec_ready(chip, ALI_CSPSR_WRITE_OK); |
snd_intel8x0_ali_codec_ready(chip, ALI_CSPSR_WRITE_OK); |
674 |
spin_unlock(&chip->ac97_lock); |
spin_unlock(&chip->ac97_lock); |
675 |
} |
} |
709 |
ichdev->frags = ichdev->size / ichdev->fragsize; |
ichdev->frags = ichdev->size / ichdev->fragsize; |
710 |
} |
} |
711 |
iputbyte(chip, port + ICH_REG_OFF_LVI, ichdev->lvi = ICH_REG_LVI_MASK); |
iputbyte(chip, port + ICH_REG_OFF_LVI, ichdev->lvi = ICH_REG_LVI_MASK); |
712 |
|
iputbyte(chip, port + ICH_REG_OFF_CIV, 0); |
713 |
ichdev->lvi_frag = ICH_REG_LVI_MASK % ichdev->frags; |
ichdev->lvi_frag = ICH_REG_LVI_MASK % ichdev->frags; |
714 |
ichdev->position = 0; |
ichdev->position = 0; |
715 |
#if 0 |
#if 0 |
758 |
spin_lock(&chip->reg_lock); |
spin_lock(&chip->reg_lock); |
759 |
status = igetdword(chip, chip->int_sta_reg); |
status = igetdword(chip, chip->int_sta_reg); |
760 |
if ((status & chip->int_sta_mask) == 0) { |
if ((status & chip->int_sta_mask) == 0) { |
761 |
|
if (status) |
762 |
|
iputdword(chip, chip->int_sta_reg, status); |
763 |
spin_unlock(&chip->reg_lock); |
spin_unlock(&chip->reg_lock); |
764 |
return IRQ_NONE; |
return IRQ_NONE; |
765 |
} |
} |
808 |
} |
} |
809 |
iputbyte(chip, port + ICH_REG_OFF_CR, val); |
iputbyte(chip, port + ICH_REG_OFF_CR, val); |
810 |
if (cmd == SNDRV_PCM_TRIGGER_STOP) { |
if (cmd == SNDRV_PCM_TRIGGER_STOP) { |
811 |
/* reset whole DMA things */ |
/* wait until DMA stopped */ |
812 |
while (!(igetbyte(chip, port + ichdev->roff_sr) & ICH_DCH)) ; |
while (!(igetbyte(chip, port + ichdev->roff_sr) & ICH_DCH)) ; |
813 |
|
/* reset whole DMA things */ |
814 |
iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS); |
iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS); |
815 |
} |
} |
816 |
return 0; |
return 0; |
821 |
intel8x0_t *chip = snd_pcm_substream_chip(substream); |
intel8x0_t *chip = snd_pcm_substream_chip(substream); |
822 |
ichdev_t *ichdev = get_ichdev(substream); |
ichdev_t *ichdev = get_ichdev(substream); |
823 |
unsigned long port = ichdev->reg_offset; |
unsigned long port = ichdev->reg_offset; |
824 |
|
static int fiforeg[] = { ICHREG(ALI_FIFOCR1), ICHREG(ALI_FIFOCR2), ICHREG(ALI_FIFOCR3) }; |
825 |
|
unsigned int val, fifo; |
826 |
|
|
827 |
|
val = igetdword(chip, ICHREG(ALI_DMACR)); |
828 |
switch (cmd) { |
switch (cmd) { |
829 |
case SNDRV_PCM_TRIGGER_START: |
case SNDRV_PCM_TRIGGER_START: |
830 |
|
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
831 |
case SNDRV_PCM_TRIGGER_RESUME: |
case SNDRV_PCM_TRIGGER_RESUME: |
832 |
|
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
833 |
|
/* clear FIFO for synchronization of channels */ |
834 |
|
fifo = igetdword(chip, fiforeg[ichdev->ali_slot / 4]); |
835 |
|
fifo &= ~(0xff << (ichdev->ali_slot % 4)); |
836 |
|
fifo |= 0x83 << (ichdev->ali_slot % 4); |
837 |
|
iputdword(chip, fiforeg[ichdev->ali_slot / 4], fifo); |
838 |
|
} |
839 |
iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE); |
iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE); |
840 |
iputbyte(chip, ICHREG(ALI_DMACR), 1 << ichdev->ali_slot); |
val &= ~(1 << (ichdev->ali_slot + 16)); /* clear PAUSE flag */ |
841 |
|
iputdword(chip, ICHREG(ALI_DMACR), val | (1 << ichdev->ali_slot)); /* start DMA */ |
842 |
break; |
break; |
843 |
case SNDRV_PCM_TRIGGER_STOP: |
case SNDRV_PCM_TRIGGER_STOP: |
844 |
|
case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
845 |
case SNDRV_PCM_TRIGGER_SUSPEND: |
case SNDRV_PCM_TRIGGER_SUSPEND: |
846 |
iputbyte(chip, ICHREG(ALI_DMACR), 1 << (ichdev->ali_slot + 8)); |
iputdword(chip, ICHREG(ALI_DMACR), val | (1 << (ichdev->ali_slot + 16))); /* pause */ |
847 |
iputbyte(chip, port + ICH_REG_OFF_CR, 0); |
iputbyte(chip, port + ICH_REG_OFF_CR, 0); |
848 |
/* reset whole DMA things */ |
while (igetbyte(chip, port + ICH_REG_OFF_CR)) |
|
while (!(igetbyte(chip, port + ICH_REG_OFF_CR))) |
|
849 |
; |
; |
850 |
|
if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH) |
851 |
|
break; |
852 |
|
/* reset whole DMA things */ |
853 |
iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS); |
iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS); |
854 |
/* clear interrupts */ |
/* clear interrupts */ |
855 |
iputbyte(chip, port + ICH_REG_OFF_SR, igetbyte(chip, port + ICH_REG_OFF_SR) | 0x1e); |
iputbyte(chip, port + ICH_REG_OFF_SR, igetbyte(chip, port + ICH_REG_OFF_SR) | 0x1e); |
856 |
iputdword(chip, ICHREG(ALI_INTERRUPTSR), |
iputdword(chip, ICHREG(ALI_INTERRUPTSR), |
857 |
igetdword(chip, ICHREG(ALI_INTERRUPTSR)) & (1 << (ichdev->ali_slot + 8))); |
igetdword(chip, ICHREG(ALI_INTERRUPTSR)) & ichdev->int_sta_mask); |
|
break; |
|
|
case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
|
|
iputbyte(chip, port + ICH_REG_OFF_CR, 0); |
|
|
break; |
|
|
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
|
|
iputbyte(chip, ICHREG(ALI_DMACR), 1 << ichdev->ali_slot); |
|
858 |
break; |
break; |
859 |
default: |
default: |
860 |
return -EINVAL; |
return -EINVAL; |
875 |
|
|
876 |
static void snd_intel8x0_setup_multi_channels(intel8x0_t *chip, int channels) |
static void snd_intel8x0_setup_multi_channels(intel8x0_t *chip, int channels) |
877 |
{ |
{ |
878 |
unsigned int cnt = igetdword(chip, ICHREG(GLOB_CNT)); |
unsigned int cnt; |
879 |
if (chip->device_type == DEVICE_SIS) { |
switch (chip->device_type) { |
880 |
|
case DEVICE_ALI: |
881 |
|
cnt = igetdword(chip, ICHREG(ALI_SCR)); |
882 |
|
cnt &= ~ICH_ALI_SC_PCM_246_MASK; |
883 |
|
if (chip->multi4 && channels == 4) |
884 |
|
cnt |= ICH_ALI_SC_PCM_4; |
885 |
|
else if (chip->multi6 && channels == 6) |
886 |
|
cnt |= ICH_ALI_SC_PCM_6; |
887 |
|
iputdword(chip, ICHREG(ALI_SCR), cnt); |
888 |
|
break; |
889 |
|
case DEVICE_SIS: |
890 |
|
cnt = igetdword(chip, ICHREG(GLOB_CNT)); |
891 |
cnt &= ~ICH_SIS_PCM_246_MASK; |
cnt &= ~ICH_SIS_PCM_246_MASK; |
892 |
if (chip->multi4 && channels == 4) |
if (chip->multi4 && channels == 4) |
893 |
cnt |= ICH_SIS_PCM_4; |
cnt |= ICH_SIS_PCM_4; |
894 |
else if (chip->multi6 && channels == 6) |
else if (chip->multi6 && channels == 6) |
895 |
cnt |= ICH_SIS_PCM_6; |
cnt |= ICH_SIS_PCM_6; |
896 |
} else { |
iputdword(chip, ICHREG(GLOB_CNT), cnt); |
897 |
|
break; |
898 |
|
default: |
899 |
|
cnt = igetdword(chip, ICHREG(GLOB_CNT)); |
900 |
cnt &= ~ICH_PCM_246_MASK; |
cnt &= ~ICH_PCM_246_MASK; |
901 |
if (chip->multi4 && channels == 4) |
if (chip->multi4 && channels == 4) |
902 |
cnt |= ICH_PCM_4; |
cnt |= ICH_PCM_4; |
903 |
else if (chip->multi6 && channels == 6) |
else if (chip->multi6 && channels == 6) |
904 |
cnt |= ICH_PCM_6; |
cnt |= ICH_PCM_6; |
905 |
|
iputdword(chip, ICHREG(GLOB_CNT), cnt); |
906 |
|
break; |
907 |
} |
} |
|
iputdword(chip, ICHREG(GLOB_CNT), cnt); |
|
908 |
} |
} |
909 |
|
|
910 |
static int snd_intel8x0_pcm_prepare(snd_pcm_substream_t * substream) |
static int snd_intel8x0_pcm_prepare(snd_pcm_substream_t * substream) |
917 |
ichdev->physbuf = runtime->dma_addr; |
ichdev->physbuf = runtime->dma_addr; |
918 |
ichdev->size = snd_pcm_lib_buffer_bytes(substream); |
ichdev->size = snd_pcm_lib_buffer_bytes(substream); |
919 |
ichdev->fragsize = snd_pcm_lib_period_bytes(substream); |
ichdev->fragsize = snd_pcm_lib_period_bytes(substream); |
920 |
if (ichdev->ichd == ICHD_PCMOUT && chip->device_type != DEVICE_ALI) { |
if (ichdev->ichd == ICHD_PCMOUT) { |
921 |
spin_lock(&chip->reg_lock); |
spin_lock(&chip->reg_lock); |
922 |
snd_intel8x0_setup_multi_channels(chip, runtime->channels); |
snd_intel8x0_setup_multi_channels(chip, runtime->channels); |
923 |
spin_unlock(&chip->reg_lock); |
spin_unlock(&chip->reg_lock); |
926 |
for (i = 0; i < 3; i++) |
for (i = 0; i < 3; i++) |
927 |
if (ichdev->ac97_rate_regs[i]) |
if (ichdev->ac97_rate_regs[i]) |
928 |
snd_ac97_set_rate(ichdev->ac97, ichdev->ac97_rate_regs[i], runtime->rate); |
snd_ac97_set_rate(ichdev->ac97, ichdev->ac97_rate_regs[i], runtime->rate); |
929 |
|
/* FIXME: hack to enable spdif support */ |
930 |
|
if (ichdev->ichd == ICHD_PCMOUT && chip->device_type == DEVICE_SIS) |
931 |
|
snd_ac97_set_rate(ichdev->ac97, AC97_SPDIF, runtime->rate); |
932 |
} |
} |
933 |
snd_intel8x0_setup_periods(chip, ichdev); |
snd_intel8x0_setup_periods(chip, ichdev); |
934 |
return 0; |
return 0; |
938 |
{ |
{ |
939 |
intel8x0_t *chip = snd_pcm_substream_chip(substream); |
intel8x0_t *chip = snd_pcm_substream_chip(substream); |
940 |
ichdev_t *ichdev = get_ichdev(substream); |
ichdev_t *ichdev = get_ichdev(substream); |
941 |
size_t ptr; |
size_t ptr1, ptr; |
942 |
|
|
943 |
ptr = ichdev->fragsize1; |
ptr1 = igetword(chip, ichdev->reg_offset + ichdev->roff_picb) << chip->pcm_pos_shift; |
944 |
ptr -= igetword(chip, ichdev->reg_offset + ichdev->roff_picb) << chip->pcm_pos_shift; |
if (ptr1 != 0) |
945 |
|
ptr = ichdev->fragsize1 - ptr1; |
946 |
|
else |
947 |
|
ptr = 0; |
948 |
ptr += ichdev->position; |
ptr += ichdev->position; |
949 |
|
if (ptr >= ichdev->size) |
950 |
|
return 0; |
951 |
return bytes_to_frames(substream->runtime, ptr); |
return bytes_to_frames(substream->runtime, ptr); |
952 |
} |
} |
953 |
|
|
960 |
SNDRV_PCM_INFO_RESUME), |
SNDRV_PCM_INFO_RESUME), |
961 |
.formats = SNDRV_PCM_FMTBIT_S16_LE, |
.formats = SNDRV_PCM_FMTBIT_S16_LE, |
962 |
.rates = SNDRV_PCM_RATE_48000, |
.rates = SNDRV_PCM_RATE_48000, |
963 |
.rate_min = 8000, |
.rate_min = 48000, |
964 |
.rate_max = 48000, |
.rate_max = 48000, |
965 |
.channels_min = 2, |
.channels_min = 2, |
966 |
.channels_max = 2, |
.channels_max = 2, |
1000 |
{ |
{ |
1001 |
intel8x0_t *chip = snd_pcm_substream_chip(substream); |
intel8x0_t *chip = snd_pcm_substream_chip(substream); |
1002 |
snd_pcm_runtime_t *runtime = substream->runtime; |
snd_pcm_runtime_t *runtime = substream->runtime; |
1003 |
|
static unsigned int i, rates[] = { |
1004 |
|
/* ATTENTION: these values depend on the definition in pcm.h! */ |
1005 |
|
5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000 |
1006 |
|
}; |
1007 |
int err; |
int err; |
1008 |
|
|
1009 |
ichdev->substream = substream; |
ichdev->substream = substream; |
1010 |
runtime->hw = snd_intel8x0_stream; |
runtime->hw = snd_intel8x0_stream; |
1011 |
if (ichdev->ac97 && ichdev->ac97_rates_idx >= 0) |
if (ichdev->ac97 && ichdev->ac97_rates_idx >= 0) { |
1012 |
runtime->hw.rates = ichdev->ac97->rates[ichdev->ac97_rates_idx]; |
runtime->hw.rates = ichdev->ac97->rates[ichdev->ac97_rates_idx]; |
1013 |
if (!(runtime->hw.rates & SNDRV_PCM_RATE_8000)) |
for (i = 0; i < ARRAY_SIZE(rates); i++) { |
1014 |
runtime->hw.rate_min = 48000; |
if (runtime->hw.rates & (1 << i)) { |
1015 |
|
runtime->hw.rate_min = rates[i]; |
1016 |
|
break; |
1017 |
|
} |
1018 |
|
} |
1019 |
|
} |
1020 |
if (chip->device_type == DEVICE_SIS) { |
if (chip->device_type == DEVICE_SIS) { |
1021 |
runtime->hw.buffer_bytes_max = 64*1024; |
runtime->hw.buffer_bytes_max = 64*1024; |
1022 |
runtime->hw.period_bytes_max = 64*1024; |
runtime->hw.period_bytes_max = 64*1024; |
1132 |
static int snd_intel8x0_ali_ac97spdifout_open(snd_pcm_substream_t * substream) |
static int snd_intel8x0_ali_ac97spdifout_open(snd_pcm_substream_t * substream) |
1133 |
{ |
{ |
1134 |
intel8x0_t *chip = snd_pcm_substream_chip(substream); |
intel8x0_t *chip = snd_pcm_substream_chip(substream); |
1135 |
|
unsigned long flags; |
1136 |
|
unsigned int val; |
1137 |
|
|
1138 |
|
spin_lock_irqsave(&chip->reg_lock, flags); |
1139 |
|
val = igetdword(chip, ICHREG(ALI_INTERFACECR)); |
1140 |
|
val |= ICH_ALI_IF_AC97SP; |
1141 |
|
/* also needs to set ALI_SC_CODEC_SPDF correctly */ |
1142 |
|
spin_unlock_irqrestore(&chip->reg_lock, flags); |
1143 |
|
|
1144 |
return snd_intel8x0_pcm_open(substream, &chip->ichd[ALID_AC97SPDIFOUT]); |
return snd_intel8x0_pcm_open(substream, &chip->ichd[ALID_AC97SPDIFOUT]); |
1145 |
} |
} |
1147 |
static int snd_intel8x0_ali_ac97spdifout_close(snd_pcm_substream_t * substream) |
static int snd_intel8x0_ali_ac97spdifout_close(snd_pcm_substream_t * substream) |
1148 |
{ |
{ |
1149 |
intel8x0_t *chip = snd_pcm_substream_chip(substream); |
intel8x0_t *chip = snd_pcm_substream_chip(substream); |
1150 |
|
unsigned long flags; |
1151 |
|
unsigned int val; |
1152 |
|
|
1153 |
chip->ichd[ALID_AC97SPDIFOUT].substream = NULL; |
chip->ichd[ALID_AC97SPDIFOUT].substream = NULL; |
1154 |
|
spin_lock_irqsave(&chip->reg_lock, flags); |
1155 |
|
val = igetdword(chip, ICHREG(ALI_INTERFACECR)); |
1156 |
|
val &= ~ICH_ALI_IF_AC97SP; |
1157 |
|
spin_unlock_irqrestore(&chip->reg_lock, flags); |
1158 |
|
|
1159 |
return 0; |
return 0; |
1160 |
} |
} |
1161 |
|
|
1174 |
return 0; |
return 0; |
1175 |
} |
} |
1176 |
|
|
1177 |
|
#if 0 // NYI |
1178 |
static int snd_intel8x0_ali_spdifout_open(snd_pcm_substream_t * substream) |
static int snd_intel8x0_ali_spdifout_open(snd_pcm_substream_t * substream) |
1179 |
{ |
{ |
1180 |
intel8x0_t *chip = snd_pcm_substream_chip(substream); |
intel8x0_t *chip = snd_pcm_substream_chip(substream); |
1189 |
chip->ichd[ALID_SPDIFOUT].substream = NULL; |
chip->ichd[ALID_SPDIFOUT].substream = NULL; |
1190 |
return 0; |
return 0; |
1191 |
} |
} |
1192 |
|
#endif |
1193 |
|
|
1194 |
static snd_pcm_ops_t snd_intel8x0_playback_ops = { |
static snd_pcm_ops_t snd_intel8x0_playback_ops = { |
1195 |
.open = snd_intel8x0_playback_open, |
.open = snd_intel8x0_playback_open, |
1312 |
.pointer = snd_intel8x0_pcm_pointer, |
.pointer = snd_intel8x0_pcm_pointer, |
1313 |
}; |
}; |
1314 |
|
|
1315 |
|
#if 0 // NYI |
1316 |
static snd_pcm_ops_t snd_intel8x0_ali_spdifout_ops = { |
static snd_pcm_ops_t snd_intel8x0_ali_spdifout_ops = { |
1317 |
.open = snd_intel8x0_ali_spdifout_open, |
.open = snd_intel8x0_ali_spdifout_open, |
1318 |
.close = snd_intel8x0_ali_spdifout_close, |
.close = snd_intel8x0_ali_spdifout_close, |
1323 |
.trigger = snd_intel8x0_pcm_trigger, |
.trigger = snd_intel8x0_pcm_trigger, |
1324 |
.pointer = snd_intel8x0_pcm_pointer, |
.pointer = snd_intel8x0_pcm_pointer, |
1325 |
}; |
}; |
1326 |
|
#endif // NYI |
1327 |
|
|
1328 |
struct ich_pcm_table { |
struct ich_pcm_table { |
1329 |
char *suffix; |
char *suffix; |
1445 |
}, |
}, |
1446 |
{ |
{ |
1447 |
.suffix = "IEC958", |
.suffix = "IEC958", |
1448 |
.playback_ops = &snd_intel8x0_ali_spdifout_ops, |
.playback_ops = &snd_intel8x0_ali_ac97spdifout_ops, |
1449 |
.capture_ops = &snd_intel8x0_ali_spdifin_ops, |
.capture_ops = &snd_intel8x0_ali_spdifin_ops, |
1450 |
.prealloc_size = 64 * 1024, |
.prealloc_size = 64 * 1024, |
1451 |
.prealloc_max_size = 128 * 1024, |
.prealloc_max_size = 128 * 1024, |
1452 |
|
.ac97_idx = ALID_AC97SPDIFOUT, |
1453 |
}, |
}, |
1454 |
|
#if 0 // NYI |
1455 |
{ |
{ |
1456 |
.suffix = "AC97 IEC958", |
.suffix = "HW IEC958", |
1457 |
.playback_ops = &snd_intel8x0_ali_ac97spdifout_ops, |
.playback_ops = &snd_intel8x0_ali_spdifout_ops, |
1458 |
.prealloc_size = 64 * 1024, |
.prealloc_size = 64 * 1024, |
1459 |
.prealloc_max_size = 128 * 1024, |
.prealloc_max_size = 128 * 1024, |
|
.ac97_idx = ALID_AC97SPDIFOUT, |
|
1460 |
}, |
}, |
1461 |
|
#endif |
1462 |
}; |
}; |
1463 |
|
|
1464 |
static int __devinit snd_intel8x0_pcm(intel8x0_t *chip) |
static int __devinit snd_intel8x0_pcm(intel8x0_t *chip) |
1537 |
}; |
}; |
1538 |
|
|
1539 |
static struct _ac97_rate_regs ali_ac97_rate_regs[] __devinitdata = { |
static struct _ac97_rate_regs ali_ac97_rate_regs[] __devinitdata = { |
1540 |
|
#if 0 /* FIXME: my test board doens't work well with VRA... */ |
1541 |
{ ALID_PCMOUT, { AC97_PCM_FRONT_DAC_RATE, AC97_PCM_SURR_DAC_RATE, AC97_PCM_LFE_DAC_RATE }, AC97_RATES_FRONT_DAC }, |
{ ALID_PCMOUT, { AC97_PCM_FRONT_DAC_RATE, AC97_PCM_SURR_DAC_RATE, AC97_PCM_LFE_DAC_RATE }, AC97_RATES_FRONT_DAC }, |
1542 |
{ ALID_PCMIN, { AC97_PCM_LR_ADC_RATE, 0, 0 }, AC97_RATES_ADC }, |
{ ALID_PCMIN, { AC97_PCM_LR_ADC_RATE, 0, 0 }, AC97_RATES_ADC }, |
1543 |
{ ALID_MIC, { AC97_PCM_MIC_ADC_RATE, 0, 0 }, AC97_RATES_MIC_ADC }, |
{ ALID_MIC, { AC97_PCM_MIC_ADC_RATE, 0, 0 }, AC97_RATES_MIC_ADC }, |
1544 |
{ ALID_AC97SPDIFOUT, { AC97_SPDIF, 0, 0 }, AC97_RATES_SPDIF }, |
{ ALID_AC97SPDIFOUT, { AC97_SPDIF, 0, 0 }, AC97_RATES_SPDIF }, |
1545 |
{ ALID_SPDIFOUT, { 0, 0, 0 }, -1 }, |
{ ALID_SPDIFOUT, { 0, 0, 0 }, -1 }, |
1546 |
{ ALID_SPDIFIN, { 0, 0, 0 }, -1 }, |
{ ALID_SPDIFIN, { 0, 0, 0 }, -1 }, |
1547 |
|
#else |
1548 |
|
{ ALID_PCMOUT, { AC97_PCM_FRONT_DAC_RATE }, -1 }, |
1549 |
|
{ ALID_PCMIN, { AC97_PCM_LR_ADC_RATE }, -1 }, |
1550 |
|
{ ALID_MIC, { AC97_PCM_MIC_ADC_RATE }, -1 }, |
1551 |
|
{ ALID_AC97SPDIFOUT, { AC97_SPDIF }, -1 }, |
1552 |
|
{ ALID_SPDIFOUT, { }, -1 }, |
1553 |
|
{ ALID_SPDIFIN, { }, -1 }, |
1554 |
|
#endif |
1555 |
}; |
}; |
1556 |
|
|
1557 |
static struct ac97_quirk ac97_quirks[] __devinitdata = { |
static struct ac97_quirk ac97_quirks[] __devinitdata = { |
1558 |
{ 0x1028, 0x0126, "Dell Optiplex GX260", AC97_TUNE_HP_ONLY }, |
{ 0x1028, 0x0126, "Dell Optiplex GX260", AC97_TUNE_HP_ONLY }, |
1559 |
{ 0x1734, 0x0088, "Fujitsu-Siemens D1522", AC97_TUNE_HP_ONLY }, |
{ 0x1734, 0x0088, "Fujitsu-Siemens D1522", AC97_TUNE_HP_ONLY }, |
1560 |
{ 0x10f1, 0x2665, "Fujitsu-Siemens Celcius", AC97_TUNE_HP_ONLY }, |
{ 0x10f1, 0x2665, "Fujitsu-Siemens Celcius", AC97_TUNE_HP_ONLY }, |
1561 |
|
{ 0x110a, 0x0056, "Fujitsu-Siemens Scenic", AC97_TUNE_HP_ONLY }, |
1562 |
{ 0x8086, 0x4d44, "Intel D850EMV2", AC97_TUNE_HP_ONLY }, |
{ 0x8086, 0x4d44, "Intel D850EMV2", AC97_TUNE_HP_ONLY }, |
1563 |
{ 0x4144, 0x5360, "AMD64 Motherboard", AC97_TUNE_HP_ONLY }, |
/* { 0x4144, 0x5360, "AMD64 Motherboard", AC97_TUNE_HP_ONLY }, */ /* FIXME: this seems invalid */ |
1564 |
{ 0x1043, 0x80b0, "ASUS P4PE Mobo", AC97_TUNE_SWAP_SURROUND }, |
{ 0x1043, 0x80b0, "ASUS P4PE Mobo", AC97_TUNE_SWAP_SURROUND }, |
1565 |
{ } /* terminator */ |
{ } /* terminator */ |
1566 |
}; |
}; |
1570 |
ac97_t ac97, *x97; |
ac97_t ac97, *x97; |
1571 |
ichdev_t *ichdev; |
ichdev_t *ichdev; |
1572 |
int err; |
int err; |
1573 |
unsigned int i, num, channels = 2, codecs, _codecs; |
unsigned int i, num, codecs, _codecs; |
1574 |
unsigned int glob_sta = 0; |
unsigned int glob_sta = 0; |
1575 |
struct _ac97_rate_regs *tbl; |
struct _ac97_rate_regs *tbl; |
1576 |
|
int spdif_idx = -1; /* disabled */ |
1577 |
|
|
1578 |
switch (chip->device_type) { |
switch (chip->device_type) { |
1579 |
case DEVICE_NFORCE: |
case DEVICE_NFORCE: |
1580 |
tbl = nforce_ac97_rate_regs; |
tbl = nforce_ac97_rate_regs; |
1581 |
|
spdif_idx = NVD_SPBAR; |
1582 |
break; |
break; |
1583 |
case DEVICE_ALI: |
case DEVICE_ALI: |
1584 |
tbl = ali_ac97_rate_regs; |
tbl = ali_ac97_rate_regs; |
1585 |
|
spdif_idx = ALID_AC97SPDIFOUT; |
1586 |
break; |
break; |
1587 |
default: |
default: |
1588 |
tbl = intel_ac97_rate_regs; |
tbl = intel_ac97_rate_regs; |
1589 |
|
if (chip->device_type == DEVICE_INTEL_ICH4) |
1590 |
|
spdif_idx = ICHD_SPBAR; |
1591 |
break; |
break; |
1592 |
}; |
}; |
1593 |
for (i = 0; i < chip->bdbars_count; i++) { |
for (i = 0; i < chip->bdbars_count; i++) { |
1611 |
glob_sta = igetdword(chip, ICHREG(GLOB_STA)); |
glob_sta = igetdword(chip, ICHREG(GLOB_STA)); |
1612 |
ac97.write = snd_intel8x0_codec_write; |
ac97.write = snd_intel8x0_codec_write; |
1613 |
ac97.read = snd_intel8x0_codec_read; |
ac97.read = snd_intel8x0_codec_read; |
|
if (glob_sta & ICH_PCM_6) |
|
|
channels = 6; |
|
|
else if (glob_sta & ICH_PCM_4) |
|
|
channels = 4; |
|
1614 |
if (chip->device_type == DEVICE_INTEL_ICH4) { |
if (chip->device_type == DEVICE_INTEL_ICH4) { |
1615 |
codecs = 0; |
codecs = 0; |
1616 |
if (glob_sta & ICH_PCR) |
if (glob_sta & ICH_PCR) |
1633 |
} else { |
} else { |
1634 |
ac97.write = snd_intel8x0_ali_codec_write; |
ac97.write = snd_intel8x0_ali_codec_write; |
1635 |
ac97.read = snd_intel8x0_ali_codec_read; |
ac97.read = snd_intel8x0_ali_codec_read; |
|
channels = 6; |
|
1636 |
codecs = 1; |
codecs = 1; |
1637 |
/* detect the secondary codec */ |
/* detect the secondary codec */ |
1638 |
for (i = 0; i < 100; i++) { |
for (i = 0; i < 100; i++) { |
1656 |
if (x97->ext_id & AC97_EI_VRM) |
if (x97->ext_id & AC97_EI_VRM) |
1657 |
chip->ichd[ICHD_MIC].ac97 = x97; |
chip->ichd[ICHD_MIC].ac97 = x97; |
1658 |
/* spdif */ |
/* spdif */ |
1659 |
if (x97->ext_id & AC97_EI_SPDIF) { |
if ((x97->ext_id & AC97_EI_SPDIF) && spdif_idx >= 0) |
1660 |
switch (chip->device_type) { |
chip->ichd[spdif_idx].ac97 = x97; |
|
case DEVICE_INTEL_ICH4: |
|
|
chip->ichd[ICHD_SPBAR].ac97 = x97; |
|
|
break; |
|
|
case DEVICE_NFORCE: |
|
|
chip->ichd[NVD_SPBAR].ac97 = x97; |
|
|
break; |
|
|
case DEVICE_ALI: |
|
|
chip->ichd[ALID_AC97SPDIFOUT].ac97 = x97; |
|
|
break; |
|
|
} |
|
|
} |
|
1661 |
/* make sure, that we have DACs at right slot for rev2.2 */ |
/* make sure, that we have DACs at right slot for rev2.2 */ |
1662 |
if (ac97_is_rev22(x97)) |
if (ac97_is_rev22(x97)) |
1663 |
snd_ac97_update_bits(x97, AC97_EXTENDED_ID, AC97_EI_DACS_SLOT_MASK, 0); |
snd_ac97_update_bits(x97, AC97_EXTENDED_ID, AC97_EI_DACS_SLOT_MASK, 0); |
1688 |
chip->ichd[ICHD_PCM2IN].ac97 == x97) |
chip->ichd[ICHD_PCM2IN].ac97 == x97) |
1689 |
chip->ichd[ICHD_MIC2].ac97 = x97; |
chip->ichd[ICHD_MIC2].ac97 = x97; |
1690 |
} |
} |
|
if (x97->ext_id & AC97_EI_SPDIF) { |
|
|
if (chip->ichd[ICHD_SPBAR].ac97 == NULL) |
|
|
chip->ichd[ICHD_SPBAR].ac97 = x97; |
|
|
} |
|
1691 |
break; |
break; |
1692 |
default: |
default: |
1693 |
if (x97->ext_id & AC97_EI_VRM) { |
if (x97->ext_id & AC97_EI_VRM) { |
1694 |
if (chip->ichd[ICHD_MIC].ac97 == NULL) |
if (chip->ichd[ICHD_MIC].ac97 == NULL) |
1695 |
chip->ichd[ICHD_MIC].ac97 = x97; |
chip->ichd[ICHD_MIC].ac97 = x97; |
1696 |
} |
} |
|
if ((x97->ext_id & AC97_EI_SPDIF) && |
|
|
chip->device_type == DEVICE_NFORCE) { |
|
|
if (chip->ichd[NVD_SPBAR].ac97 == NULL) |
|
|
chip->ichd[NVD_SPBAR].ac97 = x97; |
|
|
} |
|
1697 |
break; |
break; |
1698 |
} |
} |
1699 |
|
if ((x97->ext_id & AC97_EI_SPDIF) && spdif_idx >= 0) { |
1700 |
|
if (chip->ichd[spdif_idx].ac97 == NULL) |
1701 |
|
chip->ichd[spdif_idx].ac97 = x97; |
1702 |
|
} |
1703 |
} |
} |
1704 |
|
|
1705 |
__skip_secondary: |
__skip_secondary: |
1729 |
if (x97->scaps & AC97_SCAP_CENTER_LFE_DAC) |
if (x97->scaps & AC97_SCAP_CENTER_LFE_DAC) |
1730 |
chip->multi6 = 1; |
chip->multi6 = 1; |
1731 |
} |
} |
1732 |
if (codecs > 1) { |
if (chip->device_type == DEVICE_ALI && chip->ac97[1]) { |
1733 |
|
/* set secondary codec id */ |
1734 |
|
iputdword(chip, ICHREG(ALI_SSR), |
1735 |
|
(igetdword(chip, ICHREG(ALI_SSR)) & ~ICH_ALI_SS_SEC_ID) | |
1736 |
|
(chip->ac97[1]->addr << 5)); |
1737 |
|
} |
1738 |
|
if (codecs > 1 && !chip->multi6) { |
1739 |
/* assign right slots for rev2.2 codecs */ |
/* assign right slots for rev2.2 codecs */ |
1740 |
i = 1; |
i = 1; |
1741 |
if (chip->multi4) |
for ( ; i < codecs && !chip->multi4; i++) { |
|
goto __6ch; |
|
|
for ( ; i < codecs; i++) { |
|
1742 |
x97 = chip->ac97[i]; |
x97 = chip->ac97[i]; |
1743 |
if (!ac97_is_audio(x97)) |
if (!ac97_is_audio(x97)) |
1744 |
continue; |
continue; |
1745 |
if (ac97_is_rev22(x97)) { |
if (ac97_is_rev22(x97)) { |
1746 |
snd_ac97_update_bits(x97, AC97_EXTENDED_ID, AC97_EI_DACS_SLOT_MASK, 1); |
snd_ac97_update_bits(x97, AC97_EXTENDED_ID, AC97_EI_DACS_SLOT_MASK, 1); |
1747 |
chip->multi4 = 1; |
chip->multi4 = 1; |
|
break; |
|
1748 |
} |
} |
1749 |
} |
} |
|
__6ch: |
|
1750 |
for ( ; i < codecs && chip->multi4; i++) { |
for ( ; i < codecs && chip->multi4; i++) { |
1751 |
x97 = chip->ac97[i]; |
x97 = chip->ac97[i]; |
1752 |
if (!ac97_is_audio(x97)) |
if (!ac97_is_audio(x97)) |
1759 |
} |
} |
1760 |
/* ok, some older codecs might support only AMAP */ |
/* ok, some older codecs might support only AMAP */ |
1761 |
if (!chip->multi4) { |
if (!chip->multi4) { |
1762 |
|
int cnums = 0; |
1763 |
for (i = 1; i < codecs; i++) { |
for (i = 1; i < codecs; i++) { |
1764 |
x97 = chip->ac97[i]; |
x97 = chip->ac97[i]; |
1765 |
if (!ac97_is_audio(x97)) |
if (!ac97_is_audio(x97)) |
1766 |
continue; |
continue; |
1767 |
if (ac97_can_amap(x97)) { |
if (ac97_can_amap(x97)) { |
1768 |
if (x97->addr == 1) { |
if (x97->addr > 0) |
1769 |
chip->multi4 = 1; |
cnums++; |
|
break; |
|
|
} |
|
|
} |
|
|
} |
|
|
for ( ; i < codecs && chip->multi4; i++) { |
|
|
if (!ac97_is_audio(x97)) |
|
|
continue; |
|
|
if (ac97_can_amap(x97)) { |
|
|
if (x97->addr == 2) { |
|
|
chip->multi6 = 1; |
|
|
break; |
|
|
} |
|
1770 |
} |
} |
1771 |
} |
} |
1772 |
|
if (cnums >= 2) |
1773 |
|
chip->multi6 = 1; |
1774 |
|
if (cnums >= 1) |
1775 |
|
chip->multi4 = 1; |
1776 |
} |
} |
1777 |
} |
} |
1778 |
chip->in_ac97_init = 0; |
chip->in_ac97_init = 0; |
1786 |
|
|
1787 |
static void do_ali_reset(intel8x0_t *chip) |
static void do_ali_reset(intel8x0_t *chip) |
1788 |
{ |
{ |
1789 |
iputdword(chip, ICHREG(ALI_SCR), 0x8000000); |
iputdword(chip, ICHREG(ALI_SCR), ICH_ALI_SC_RESET); |
1790 |
iputdword(chip, ICHREG(ALI_FIFOCR1), 0x83838383); |
iputdword(chip, ICHREG(ALI_FIFOCR1), 0x83838383); |
1791 |
iputdword(chip, ICHREG(ALI_FIFOCR2), 0x83838383); |
iputdword(chip, ICHREG(ALI_FIFOCR2), 0x83838383); |
1792 |
iputdword(chip, ICHREG(ALI_INTERFACECR), 0x04080002); /* no spdif? */ |
iputdword(chip, ICHREG(ALI_FIFOCR3), 0x83838383); |
1793 |
|
iputdword(chip, ICHREG(ALI_INTERFACECR), |
1794 |
|
ICH_ALI_IF_MC|ICH_ALI_IF_PI|ICH_ALI_IF_PO); |
1795 |
iputdword(chip, ICHREG(ALI_INTERRUPTCR), 0x00000000); |
iputdword(chip, ICHREG(ALI_INTERRUPTCR), 0x00000000); |
1796 |
iputdword(chip, ICHREG(ALI_INTERRUPTSR), 0x00000000); |
iputdword(chip, ICHREG(ALI_INTERRUPTSR), 0x00000000); |
1797 |
} |
} |
1798 |
|
|
1799 |
static void do_delay(intel8x0_t *chip) |
#define do_delay(chip) do {\ |
1800 |
{ |
set_current_state(TASK_UNINTERRUPTIBLE);\ |
1801 |
#ifdef CONFIG_PM |
schedule_timeout(1);\ |
1802 |
if (chip->in_suspend) { |
} while (0) |
|
mdelay((1000 + HZ - 1) / HZ); |
|
|
return; |
|
|
} |
|
|
#endif |
|
|
set_current_state(TASK_UNINTERRUPTIBLE); |
|
|
schedule_timeout(1); |
|
|
} |
|
1803 |
|
|
1804 |
static int snd_intel8x0_ich_chip_init(intel8x0_t *chip) |
static int snd_intel8x0_ich_chip_init(intel8x0_t *chip) |
1805 |
{ |
{ |
1926 |
unsigned int i; |
unsigned int i; |
1927 |
int err; |
int err; |
1928 |
|
|
1929 |
if (chip->device_type != DEVICE_ALI) |
if (chip->device_type != DEVICE_ALI) { |
1930 |
err = snd_intel8x0_ich_chip_init(chip); |
if ((err = snd_intel8x0_ich_chip_init(chip)) < 0) |
1931 |
else |
return err; |
1932 |
err = snd_intel8x0_ali_chip_init(chip); |
iagetword(chip, 0); /* clear semaphore flag */ |
1933 |
if (err < 0) |
} else { |
1934 |
return err; |
if ((err = snd_intel8x0_ali_chip_init(chip)) < 0) |
1935 |
|
return err; |
1936 |
iagetword(chip, 0); /* clear semaphore flag */ |
} |
1937 |
|
|
1938 |
/* disable interrupts */ |
/* disable interrupts */ |
1939 |
for (i = 0; i < chip->bdbars_count; i++) |
for (i = 0; i < chip->bdbars_count; i++) |
2018 |
return; |
return; |
2019 |
|
|
2020 |
pci_enable_device(chip->pci); |
pci_enable_device(chip->pci); |
2021 |
|
pci_set_master(chip->pci); |
2022 |
snd_intel8x0_chip_init(chip); |
snd_intel8x0_chip_init(chip); |
2023 |
for (i = 0; i < 3; i++) |
for (i = 0; i < 3; i++) |
2024 |
if (chip->ac97[i]) |
if (chip->ac97[i]) |
2028 |
snd_power_change_state(card, SNDRV_CTL_POWER_D0); |
snd_power_change_state(card, SNDRV_CTL_POWER_D0); |
2029 |
} |
} |
2030 |
|
|
|
#ifndef PCI_OLD_SUSPEND |
|
2031 |
static int snd_intel8x0_suspend(struct pci_dev *dev, u32 state) |
static int snd_intel8x0_suspend(struct pci_dev *dev, u32 state) |
2032 |
{ |
{ |
2033 |
intel8x0_t *chip = snd_magic_cast(intel8x0_t, pci_get_drvdata(dev), return -ENXIO); |
intel8x0_t *chip = snd_magic_cast(intel8x0_t, pci_get_drvdata(dev), return -ENXIO); |
2040 |
intel8x0_resume(chip); |
intel8x0_resume(chip); |
2041 |
return 0; |
return 0; |
2042 |
} |
} |
|
#else |
|
|
static void snd_intel8x0_suspend(struct pci_dev *dev) |
|
|
{ |
|
|
intel8x0_t *chip = snd_magic_cast(intel8x0_t, pci_get_drvdata(dev), return); |
|
|
intel8x0_suspend(chip); |
|
|
} |
|
|
static void snd_intel8x0_resume(struct pci_dev *dev) |
|
|
{ |
|
|
intel8x0_t *chip = snd_magic_cast(intel8x0_t, pci_get_drvdata(dev), return); |
|
|
intel8x0_resume(chip); |
|
|
} |
|
|
#endif |
|
2043 |
|
|
2044 |
/* callback */ |
/* callback */ |
2045 |
static int snd_intel8x0_set_power_state(snd_card_t *card, unsigned int power_state) |
static int snd_intel8x0_set_power_state(snd_card_t *card, unsigned int power_state) |
2100 |
iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE | ICH_STARTBM); |
iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE | ICH_STARTBM); |
2101 |
else { |
else { |
2102 |
iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE); |
iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE); |
2103 |
iputbyte(chip, ICHREG(ALI_DMACR), 1 << ichdev->ali_slot); |
iputdword(chip, ICHREG(ALI_DMACR), 1 << ichdev->ali_slot); |
2104 |
} |
} |
2105 |
do_gettimeofday(&start_time); |
do_gettimeofday(&start_time); |
2106 |
spin_unlock_irqrestore(&chip->reg_lock, flags); |
spin_unlock_irqrestore(&chip->reg_lock, flags); |
2118 |
pos += ichdev->position; |
pos += ichdev->position; |
2119 |
do_gettimeofday(&stop_time); |
do_gettimeofday(&stop_time); |
2120 |
/* stop */ |
/* stop */ |
2121 |
if (chip->device_type == DEVICE_ALI) |
if (chip->device_type == DEVICE_ALI) { |
2122 |
iputbyte(chip, ICHREG(ALI_DMACR), 1 << (ichdev->ali_slot + 8)); |
iputdword(chip, ICHREG(ALI_DMACR), 1 << (ichdev->ali_slot + 8)); |
2123 |
iputbyte(chip, port + ICH_REG_OFF_CR, 0); |
iputbyte(chip, port + ICH_REG_OFF_CR, 0); |
2124 |
/* reset whole DMA things */ |
while (igetbyte(chip, port + ICH_REG_OFF_CR)) |
2125 |
while (!(igetbyte(chip, port + ichdev->roff_sr) & ICH_DCH)) |
; |
2126 |
; |
} else { |
2127 |
|
iputbyte(chip, port + ICH_REG_OFF_CR, 0); |
2128 |
|
while (!(igetbyte(chip, port + ichdev->roff_sr) & ICH_DCH)) |
2129 |
|
; |
2130 |
|
} |
2131 |
iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS); |
iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS); |
2132 |
spin_unlock_irqrestore(&chip->reg_lock, flags); |
spin_unlock_irqrestore(&chip->reg_lock, flags); |
2133 |
|
|
2352 |
ichdev->roff_sr = ICH_REG_OFF_SR; |
ichdev->roff_sr = ICH_REG_OFF_SR; |
2353 |
ichdev->roff_picb = ICH_REG_OFF_PICB; |
ichdev->roff_picb = ICH_REG_OFF_PICB; |
2354 |
} |
} |
2355 |
ichdev->ali_slot = i + 1; /* is this right for last three devices? --jk */ |
if (device_type == DEVICE_ALI) |
2356 |
|
ichdev->ali_slot = (ichdev->reg_offset - 0x40) / 0x10; |
2357 |
} |
} |
2358 |
/* SIS7012 handles the pcm data in bytes, others are in words */ |
/* SIS7012 handles the pcm data in bytes, others are in words */ |
2359 |
chip->pcm_pos_shift = (device_type == DEVICE_SIS) ? 0 : 1; |
chip->pcm_pos_shift = (device_type == DEVICE_SIS) ? 0 : 1; |