/*
* ALSA modem driver for Intel ICH (i8x0) chipsets
*
- * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
*
* This is modified (by Sasha Khapyorsky <sashak@alsa-project.org>) version
* of ALSA ICH sound driver intel8x0.c .
*
*/
-#include <sound/driver.h>
#include <asm/io.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <sound/info.h>
#include <sound/initval.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Intel 82801AA,82901AB,i810,i820,i830,i840,i845,MX440; "
"SiS 7013; NVidia MCP/2/2S/3 modems");
MODULE_LICENSE("GPL");
int irq;
- unsigned int mmio;
- unsigned long addr;
- void __iomem *remap_addr;
- unsigned int bm_mmio;
- unsigned long bmaddr;
- void __iomem *remap_bmaddr;
+ void __iomem *addr;
+ void __iomem *bmaddr;
struct pci_dev *pci;
struct snd_card *card;
};
static struct pci_device_id snd_intel8x0m_ids[] = {
- { 0x8086, 0x2416, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82801AA */
- { 0x8086, 0x2426, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82901AB */
- { 0x8086, 0x2446, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82801BA */
- { 0x8086, 0x2486, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* ICH3 */
- { 0x8086, 0x24c6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* ICH4 */
- { 0x8086, 0x24d6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* ICH5 */
- { 0x8086, 0x266d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* ICH6 */
- { 0x8086, 0x27dd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* ICH7 */
- { 0x8086, 0x7196, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 440MX */
- { 0x1022, 0x7446, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */
- { 0x1039, 0x7013, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_SIS }, /* SI7013 */
- { 0x10de, 0x01c1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* NFORCE */
- { 0x10de, 0x0069, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* NFORCE2 */
- { 0x10de, 0x0089, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* NFORCE2s */
- { 0x10de, 0x00d9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* NFORCE3 */
+ { PCI_VDEVICE(INTEL, 0x2416), DEVICE_INTEL }, /* 82801AA */
+ { PCI_VDEVICE(INTEL, 0x2426), DEVICE_INTEL }, /* 82901AB */
+ { PCI_VDEVICE(INTEL, 0x2446), DEVICE_INTEL }, /* 82801BA */
+ { PCI_VDEVICE(INTEL, 0x2486), DEVICE_INTEL }, /* ICH3 */
+ { PCI_VDEVICE(INTEL, 0x24c6), DEVICE_INTEL }, /* ICH4 */
+ { PCI_VDEVICE(INTEL, 0x24d6), DEVICE_INTEL }, /* ICH5 */
+ { PCI_VDEVICE(INTEL, 0x266d), DEVICE_INTEL }, /* ICH6 */
+ { PCI_VDEVICE(INTEL, 0x27dd), DEVICE_INTEL }, /* ICH7 */
+ { PCI_VDEVICE(INTEL, 0x7196), DEVICE_INTEL }, /* 440MX */
+ { PCI_VDEVICE(AMD, 0x7446), DEVICE_INTEL }, /* AMD768 */
+ { PCI_VDEVICE(SI, 0x7013), DEVICE_SIS }, /* SI7013 */
+ { PCI_VDEVICE(NVIDIA, 0x01c1), DEVICE_NFORCE }, /* NFORCE */
+ { PCI_VDEVICE(NVIDIA, 0x0069), DEVICE_NFORCE }, /* NFORCE2 */
+ { PCI_VDEVICE(NVIDIA, 0x0089), DEVICE_NFORCE }, /* NFORCE2s */
+ { PCI_VDEVICE(NVIDIA, 0x00d9), DEVICE_NFORCE }, /* NFORCE3 */
#if 0
- { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
- { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
+ { PCI_VDEVICE(AMD, 0x746d), DEVICE_INTEL }, /* AMD8111 */
+ { PCI_VDEVICE(AL, 0x5455), DEVICE_ALI }, /* Ali5455 */
#endif
{ 0, }
};
* Lowlevel I/O - busmaster
*/
-static u8 igetbyte(struct intel8x0m *chip, u32 offset)
+static inline u8 igetbyte(struct intel8x0m *chip, u32 offset)
{
- if (chip->bm_mmio)
- return readb(chip->remap_bmaddr + offset);
- else
- return inb(chip->bmaddr + offset);
+ return ioread8(chip->bmaddr + offset);
}
-static u16 igetword(struct intel8x0m *chip, u32 offset)
+static inline u16 igetword(struct intel8x0m *chip, u32 offset)
{
- if (chip->bm_mmio)
- return readw(chip->remap_bmaddr + offset);
- else
- return inw(chip->bmaddr + offset);
+ return ioread16(chip->bmaddr + offset);
}
-static u32 igetdword(struct intel8x0m *chip, u32 offset)
+static inline u32 igetdword(struct intel8x0m *chip, u32 offset)
{
- if (chip->bm_mmio)
- return readl(chip->remap_bmaddr + offset);
- else
- return inl(chip->bmaddr + offset);
+ return ioread32(chip->bmaddr + offset);
}
-static void iputbyte(struct intel8x0m *chip, u32 offset, u8 val)
+static inline void iputbyte(struct intel8x0m *chip, u32 offset, u8 val)
{
- if (chip->bm_mmio)
- writeb(val, chip->remap_bmaddr + offset);
- else
- outb(val, chip->bmaddr + offset);
+ iowrite8(val, chip->bmaddr + offset);
}
-static void iputword(struct intel8x0m *chip, u32 offset, u16 val)
+static inline void iputword(struct intel8x0m *chip, u32 offset, u16 val)
{
- if (chip->bm_mmio)
- writew(val, chip->remap_bmaddr + offset);
- else
- outw(val, chip->bmaddr + offset);
+ iowrite16(val, chip->bmaddr + offset);
}
-static void iputdword(struct intel8x0m *chip, u32 offset, u32 val)
+static inline void iputdword(struct intel8x0m *chip, u32 offset, u32 val)
{
- if (chip->bm_mmio)
- writel(val, chip->remap_bmaddr + offset);
- else
- outl(val, chip->bmaddr + offset);
+ iowrite32(val, chip->bmaddr + offset);
}
/*
* Lowlevel I/O - AC'97 registers
*/
-static u16 iagetword(struct intel8x0m *chip, u32 offset)
+static inline u16 iagetword(struct intel8x0m *chip, u32 offset)
{
- if (chip->mmio)
- return readw(chip->remap_addr + offset);
- else
- return inw(chip->addr + offset);
+ return ioread16(chip->addr + offset);
}
-static void iaputword(struct intel8x0m *chip, u32 offset, u16 val)
+static inline void iaputword(struct intel8x0m *chip, u32 offset, u16 val)
{
- if (chip->mmio)
- writew(val, chip->remap_addr + offset);
- else
- outw(val, chip->addr + offset);
+ iowrite16(val, chip->addr + offset);
}
/*
static unsigned int codec_bit[3] = {
ICH_PCR, ICH_SCR, ICH_TCR
};
- snd_assert(codec < 3, return ICH_PCR);
+ if (snd_BUG_ON(codec >= 3))
+ return ICH_PCR;
return codec_bit[codec];
}
bdbar[idx + 0] = cpu_to_le32(ichdev->physbuf + (((idx >> 1) * ichdev->fragsize) % ichdev->size));
bdbar[idx + 1] = cpu_to_le32(0x80000000 | /* interrupt on completion */
ichdev->fragsize >> chip->pcm_pos_shift);
- // printk("bdbar[%i] = 0x%x [0x%x]\n", idx + 0, bdbar[idx + 0], bdbar[idx + 1]);
+ /*
+ printk(KERN_DEBUG "bdbar[%i] = 0x%x [0x%x]\n",
+ idx + 0, bdbar[idx + 0], bdbar[idx + 1]);
+ */
}
ichdev->frags = ichdev->size / ichdev->fragsize;
}
ichdev->lvi_frag = ICH_REG_LVI_MASK % ichdev->frags;
ichdev->position = 0;
#if 0
- printk("lvi_frag = %i, frags = %i, period_size = 0x%x, period_size1 = 0x%x\n",
- ichdev->lvi_frag, ichdev->frags, ichdev->fragsize, ichdev->fragsize1);
+ printk(KERN_DEBUG "lvi_frag = %i, frags = %i, period_size = 0x%x, "
+ "period_size1 = 0x%x\n",
+ ichdev->lvi_frag, ichdev->frags, ichdev->fragsize,
+ ichdev->fragsize1);
#endif
/* clear interrupts */
iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI);
ichdev->lvi_frag *
ichdev->fragsize1);
#if 0
- printk("new: bdbar[%i] = 0x%x [0x%x], prefetch = %i, all = 0x%x, 0x%x\n",
+ printk(KERN_DEBUG "new: bdbar[%i] = 0x%x [0x%x], "
+ "prefetch = %i, all = 0x%x, 0x%x\n",
ichdev->lvi * 2, ichdev->bdbar[ichdev->lvi * 2],
ichdev->bdbar[ichdev->lvi * 2 + 1], inb(ICH_REG_OFF_PIV + port),
inl(port + 4), inb(port + ICH_REG_OFF_CR));
memset(&ac97, 0, sizeof(ac97));
ac97.private_data = chip;
ac97.private_free = snd_intel8x0_mixer_free_ac97;
- ac97.scaps = AC97_SCAP_SKIP_AUDIO;
+ ac97.scaps = AC97_SCAP_SKIP_AUDIO | AC97_SCAP_POWER_SAVE;
glob_sta = igetdword(chip, ICHREG(GLOB_STA));
/* reset channels */
for (i = 0; i < chip->bdbars_count; i++)
iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, ICH_RESETREGS);
- /* --- */
- synchronize_irq(chip->irq);
- __hw_end:
- if (chip->bdbars.area)
- snd_dma_free_pages(&chip->bdbars);
- if (chip->remap_addr)
- iounmap(chip->remap_addr);
- if (chip->remap_bmaddr)
- iounmap(chip->remap_bmaddr);
+ __hw_end:
if (chip->irq >= 0)
free_irq(chip->irq, chip);
+ if (chip->bdbars.area)
+ snd_dma_free_pages(&chip->bdbars);
+ if (chip->addr)
+ pci_iounmap(chip->pci, chip->addr);
+ if (chip->bmaddr)
+ pci_iounmap(chip->pci, chip->bmaddr);
pci_release_regions(chip->pci);
pci_disable_device(chip->pci);
kfree(chip);
snd_pcm_suspend_all(chip->pcm[i]);
snd_ac97_suspend(chip->ac97);
if (chip->irq >= 0) {
- synchronize_irq(chip->irq);
free_irq(chip->irq, chip);
chip->irq = -1;
}
}
pci_set_master(pci);
if (request_irq(pci->irq, snd_intel8x0_interrupt,
- IRQF_DISABLED|IRQF_SHARED, card->shortname, chip)) {
+ IRQF_SHARED, card->shortname, chip)) {
printk(KERN_ERR "intel8x0m: unable to grab IRQ %d, "
"disabling device\n", pci->irq);
snd_card_disconnect(card);
if (device_type == DEVICE_ALI) {
/* ALI5455 has no ac97 region */
- chip->bmaddr = pci_resource_start(pci, 0);
+ chip->bmaddr = pci_iomap(pci, 0, 0);
goto port_inited;
}
- if (pci_resource_flags(pci, 2) & IORESOURCE_MEM) { /* ICH4 and Nforce */
- chip->mmio = 1;
- chip->addr = pci_resource_start(pci, 2);
- chip->remap_addr = ioremap_nocache(chip->addr,
- pci_resource_len(pci, 2));
- if (chip->remap_addr == NULL) {
- snd_printk(KERN_ERR "AC'97 space ioremap problem\n");
- snd_intel8x0_free(chip);
- return -EIO;
- }
- } else {
- chip->addr = pci_resource_start(pci, 0);
+ if (pci_resource_flags(pci, 2) & IORESOURCE_MEM) /* ICH4 and Nforce */
+ chip->addr = pci_iomap(pci, 2, 0);
+ else
+ chip->addr = pci_iomap(pci, 0, 0);
+ if (!chip->addr) {
+ snd_printk(KERN_ERR "AC'97 space ioremap problem\n");
+ snd_intel8x0_free(chip);
+ return -EIO;
}
- if (pci_resource_flags(pci, 3) & IORESOURCE_MEM) { /* ICH4 */
- chip->bm_mmio = 1;
- chip->bmaddr = pci_resource_start(pci, 3);
- chip->remap_bmaddr = ioremap_nocache(chip->bmaddr,
- pci_resource_len(pci, 3));
- if (chip->remap_bmaddr == NULL) {
- snd_printk(KERN_ERR "Controller space ioremap problem\n");
- snd_intel8x0_free(chip);
- return -EIO;
- }
- } else {
- chip->bmaddr = pci_resource_start(pci, 1);
+ if (pci_resource_flags(pci, 3) & IORESOURCE_MEM) /* ICH4 */
+ chip->bmaddr = pci_iomap(pci, 3, 0);
+ else
+ chip->bmaddr = pci_iomap(pci, 1, 0);
+ if (!chip->bmaddr) {
+ snd_printk(KERN_ERR "Controller space ioremap problem\n");
+ snd_intel8x0_free(chip);
+ return -EIO;
}
port_inited:
- if (request_irq(pci->irq, snd_intel8x0_interrupt, IRQF_DISABLED|IRQF_SHARED,
+ if (request_irq(pci->irq, snd_intel8x0_interrupt, IRQF_SHARED,
card->shortname, chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
snd_intel8x0_free(chip);
int err;
struct shortname_table *name;
- card = snd_card_new(index, id, THIS_MODULE, 0);
- if (card == NULL)
- return -ENOMEM;
+ err = snd_card_create(index, id, THIS_MODULE, 0, &card);
+ if (err < 0)
+ return err;
strcpy(card->driver, "ICH-MODEM");
strcpy(card->shortname, "Intel ICH");
snd_intel8x0m_proc_init(chip);
- sprintf(card->longname, "%s at 0x%lx, irq %i",
- card->shortname, chip->addr, chip->irq);
+ sprintf(card->longname, "%s at irq %i",
+ card->shortname, chip->irq);
if ((err = snd_card_register(card)) < 0) {
snd_card_free(card);