Newer
Older
chip->card = card;
chip->pci = pci;
chip->irq = -1;
chip->driver_type = driver_type;
chip->msi = enable_msi;
INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work);
chip->position_fix = check_position_fix(chip, position_fix[dev]);
check_probe_mask(chip, dev);
chip->single_cmd = single_cmd;
if (bdl_pos_adj[dev] < 0) {
switch (chip->driver_type) {
case AZX_DRIVER_ATI:
case AZX_DRIVER_ATIHDMI:
bdl_pos_adj[dev] = 32;
break;
default:
bdl_pos_adj[dev] = 1;
break;
}
}
#if BITS_PER_LONG != 64
/* Fix up base address on ULI M5461 */
if (chip->driver_type == AZX_DRIVER_ULI) {
u16 tmp3;
pci_read_config_word(pci, 0x40, &tmp3);
pci_write_config_word(pci, 0x40, tmp3 | 0x10);
pci_write_config_dword(pci, PCI_BASE_ADDRESS_1, 0);
}
#endif
err = pci_request_regions(pci, "ICH HD audio");
if (err < 0) {
kfree(chip);
pci_disable_device(pci);
return err;
}
chip->addr = pci_resource_start(pci, 0);
chip->remap_addr = ioremap_nocache(chip->addr, pci_resource_len(pci,0));
if (chip->remap_addr == NULL) {
snd_printk(KERN_ERR SFX "ioremap error\n");
err = -ENXIO;
goto errout;
}
if (chip->msi)
if (pci_enable_msi(pci) < 0)
chip->msi = 0;
if (azx_acquire_irq(chip, 0) < 0) {
err = -EBUSY;
goto errout;
}
pci_set_master(pci);
synchronize_irq(chip->irq);
gcap = azx_readw(chip, GCAP);
snd_printdd("chipset global capabilities = 0x%x\n", gcap);
/* allow 64bit DMA address if supported by H/W */
if ((gcap & 0x01) && !pci_set_dma_mask(pci, DMA_64BIT_MASK))
pci_set_consistent_dma_mask(pci, DMA_64BIT_MASK);
/* read number of streams from GCAP register instead of using
* hardcoded value
*/
chip->capture_streams = (gcap >> 8) & 0x0f;
chip->playback_streams = (gcap >> 12) & 0x0f;
if (!chip->playback_streams && !chip->capture_streams) {
/* gcap didn't give any info, switching to old method */
switch (chip->driver_type) {
case AZX_DRIVER_ULI:
chip->playback_streams = ULI_NUM_PLAYBACK;
chip->capture_streams = ULI_NUM_CAPTURE;
break;
case AZX_DRIVER_ATIHDMI:
chip->playback_streams = ATIHDMI_NUM_PLAYBACK;
chip->capture_streams = ATIHDMI_NUM_CAPTURE;
break;
default:
chip->playback_streams = ICH6_NUM_PLAYBACK;
chip->capture_streams = ICH6_NUM_CAPTURE;
break;
}
chip->capture_index_offset = 0;
chip->playback_index_offset = chip->capture_streams;
chip->num_streams = chip->playback_streams + chip->capture_streams;
chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev),
GFP_KERNEL);
snd_printk(KERN_ERR "cannot malloc azx_dev\n");
goto errout;
}
for (i = 0; i < chip->num_streams; i++) {
/* allocate memory for the BDL for each stream */
err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
snd_dma_pci_data(chip->pci),
BDL_SIZE, &chip->azx_dev[i].bdl);
if (err < 0) {
snd_printk(KERN_ERR SFX "cannot allocate BDL\n");
goto errout;
}
/* allocate memory for the position buffer */
err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
snd_dma_pci_data(chip->pci),
chip->num_streams * 8, &chip->posbuf);
if (err < 0) {
snd_printk(KERN_ERR SFX "cannot allocate posbuf\n");
goto errout;
if (!chip->single_cmd) {
err = azx_alloc_cmd_io(chip);
if (err < 0)
/* initialize streams */
azx_init_stream(chip);
/* initialize chip */
snd_printk(KERN_ERR SFX "no codecs found!\n");
err = -ENODEV;
goto errout;
}
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
if (err <0) {
snd_printk(KERN_ERR SFX "Error creating device [card]!\n");
goto errout;
}
strcpy(card->driver, "HDA-Intel");
strcpy(card->shortname, driver_short_names[chip->driver_type]);
sprintf(card->longname, "%s at 0x%lx irq %i",
card->shortname, chip->addr, chip->irq);
*rchip = chip;
return 0;
errout:
azx_free(chip);
return err;
}
static void power_down_all_codecs(struct azx *chip)
{
#ifdef CONFIG_SND_HDA_POWER_SAVE
/* The codecs were powered up in snd_hda_codec_new().
* Now all initialization done, so turn them down if possible
*/
struct hda_codec *codec;
list_for_each_entry(codec, &chip->bus->codec_list, list) {
snd_hda_power_down(codec);
}
#endif
}
static int __devinit azx_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
struct snd_card *card;
struct azx *chip;
if (dev >= SNDRV_CARDS)
return -ENODEV;
if (!enable[dev]) {
dev++;
return -ENOENT;
}
card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
snd_printk(KERN_ERR SFX "Error creating card!\n");
return -ENOMEM;
}
err = azx_create(card, pci, dev, pci_id->driver_data, &chip);
err = azx_codec_create(chip, model[dev], probe_mask[dev]);
snd_card_free(card);
return err;
}
/* create PCM streams */
err = azx_pcm_create(chip);
if (err < 0) {
snd_card_free(card);
return err;
}
/* create mixer controls */
err = azx_mixer_create(chip);
if (err < 0) {
snd_card_free(card);
return err;
}
snd_card_set_dev(card, &pci->dev);
err = snd_card_register(card);
if (err < 0) {
snd_card_free(card);
return err;
}
pci_set_drvdata(pci, card);
chip->running = 1;
power_down_all_codecs(chip);
Andrew Paprocki
committed
dev++;
return err;
}
static void __devexit azx_remove(struct pci_dev *pci)
{
snd_card_free(pci_get_drvdata(pci));
pci_set_drvdata(pci, NULL);
}
/* PCI IDs */
static struct pci_device_id azx_ids[] = {
/* ICH 6..10 */
{ PCI_DEVICE(0x8086, 0x2668), .driver_data = AZX_DRIVER_ICH },
{ PCI_DEVICE(0x8086, 0x27d8), .driver_data = AZX_DRIVER_ICH },
{ PCI_DEVICE(0x8086, 0x269a), .driver_data = AZX_DRIVER_ICH },
{ PCI_DEVICE(0x8086, 0x284b), .driver_data = AZX_DRIVER_ICH },
{ PCI_DEVICE(0x8086, 0x2911), .driver_data = AZX_DRIVER_ICH },
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
{ PCI_DEVICE(0x8086, 0x293e), .driver_data = AZX_DRIVER_ICH },
{ PCI_DEVICE(0x8086, 0x293f), .driver_data = AZX_DRIVER_ICH },
{ PCI_DEVICE(0x8086, 0x3a3e), .driver_data = AZX_DRIVER_ICH },
{ PCI_DEVICE(0x8086, 0x3a6e), .driver_data = AZX_DRIVER_ICH },
/* SCH */
{ PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH },
/* ATI SB 450/600 */
{ PCI_DEVICE(0x1002, 0x437b), .driver_data = AZX_DRIVER_ATI },
{ PCI_DEVICE(0x1002, 0x4383), .driver_data = AZX_DRIVER_ATI },
/* ATI HDMI */
{ PCI_DEVICE(0x1002, 0x793b), .driver_data = AZX_DRIVER_ATIHDMI },
{ PCI_DEVICE(0x1002, 0x7919), .driver_data = AZX_DRIVER_ATIHDMI },
{ PCI_DEVICE(0x1002, 0x960f), .driver_data = AZX_DRIVER_ATIHDMI },
{ PCI_DEVICE(0x1002, 0xaa00), .driver_data = AZX_DRIVER_ATIHDMI },
{ PCI_DEVICE(0x1002, 0xaa08), .driver_data = AZX_DRIVER_ATIHDMI },
{ PCI_DEVICE(0x1002, 0xaa10), .driver_data = AZX_DRIVER_ATIHDMI },
{ PCI_DEVICE(0x1002, 0xaa18), .driver_data = AZX_DRIVER_ATIHDMI },
{ PCI_DEVICE(0x1002, 0xaa20), .driver_data = AZX_DRIVER_ATIHDMI },
{ PCI_DEVICE(0x1002, 0xaa28), .driver_data = AZX_DRIVER_ATIHDMI },
{ PCI_DEVICE(0x1002, 0xaa30), .driver_data = AZX_DRIVER_ATIHDMI },
{ PCI_DEVICE(0x1002, 0xaa38), .driver_data = AZX_DRIVER_ATIHDMI },
{ PCI_DEVICE(0x1002, 0xaa40), .driver_data = AZX_DRIVER_ATIHDMI },
{ PCI_DEVICE(0x1002, 0xaa48), .driver_data = AZX_DRIVER_ATIHDMI },
/* VIA VT8251/VT8237A */
{ PCI_DEVICE(0x1106, 0x3288), .driver_data = AZX_DRIVER_VIA },
/* SIS966 */
{ PCI_DEVICE(0x1039, 0x7502), .driver_data = AZX_DRIVER_SIS },
/* ULI M5461 */
{ PCI_DEVICE(0x10b9, 0x5461), .driver_data = AZX_DRIVER_ULI },
/* NVIDIA MCP */
{ PCI_DEVICE(0x10de, 0x026c), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0371), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x03e4), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x03f0), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x044a), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x044b), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x055c), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x055d), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0774), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0775), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0776), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0777), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x07fc), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x07fd), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0ac0), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0ac1), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0ac2), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0ac3), .driver_data = AZX_DRIVER_NVIDIA },
Peer Chen
committed
{ PCI_DEVICE(0x10de, 0x0bd4), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0bd5), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0bd6), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0bd7), .driver_data = AZX_DRIVER_NVIDIA },
/* Teradici */
{ PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, azx_ids);
/* pci_driver definition */
static struct pci_driver driver = {
.name = "HDA Intel",
.id_table = azx_ids,
.probe = azx_probe,
.remove = __devexit_p(azx_remove),
#ifdef CONFIG_PM
.suspend = azx_suspend,
.resume = azx_resume,
#endif
};
static int __init alsa_card_azx_init(void)
{
return pci_register_driver(&driver);