static int __devinit snd_nm256_create(struct snd_card *card, struct pci_dev *pci, struct nm256 **chip_ret) { struct nm256 *chip; int err, pval; static struct snd_device_ops ops = { .dev_free = snd_nm256_dev_free, }; u32 addr; *chip_ret = NULL; if ((err = pci_enable_device(pci)) < 0) return err; chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) { pci_disable_device(pci); return -ENOMEM; } chip->card = card; chip->pci = pci; chip->use_cache = use_cache; spin_lock_init(&chip->reg_lock); chip->irq = -1; mutex_init(&chip->irq_mutex); /* store buffer sizes in bytes */ chip->streams[SNDRV_PCM_STREAM_PLAYBACK].bufsize = playback_bufsize * 1024; chip->streams[SNDRV_PCM_STREAM_CAPTURE].bufsize = capture_bufsize * 1024; /* * The NM256 has two memory ports. The first port is nothing * more than a chunk of video RAM, which is used as the I/O ring * buffer. The second port has the actual juicy stuff (like the * mixer and the playback engine control registers). */ chip->buffer_addr = pci_resource_start(pci, 0); chip->cport_addr = pci_resource_start(pci, 1); /* Init the memory port info. */ /* remap control port (#2) */ chip->res_cport = request_mem_region(chip->cport_addr, NM_PORT2_SIZE, card->driver); if (chip->res_cport == NULL) { snd_printk(KERN_ERR "memory region 0x%lx (size 0x%x) busy\n", chip->cport_addr, NM_PORT2_SIZE); err = -EBUSY; goto __error; } chip->cport = ioremap_nocache(chip->cport_addr, NM_PORT2_SIZE); if (chip->cport == NULL) { snd_printk(KERN_ERR "unable to map control port %lx\n", chip->cport_addr); err = -ENOMEM; goto __error; } if (!strcmp(card->driver, "NM256AV")) { /* Ok, try to see if this is a non-AC97 version of the hardware. */ pval = snd_nm256_readw(chip, NM_MIXER_PRESENCE); if ((pval & NM_PRESENCE_MASK) != NM_PRESENCE_VALUE) { if (! force_ac97) { printk(KERN_ERR "nm256: no ac97 is found!\n"); printk(KERN_ERR " force the driver to load by " "passing in the module parameter\n"); printk(KERN_ERR " force_ac97=1\n"); printk(KERN_ERR " or try sb16, opl3sa2, or " "cs423x drivers instead.\n"); err = -ENXIO; goto __error; } } chip->buffer_end = 2560 * 1024; chip->interrupt = snd_nm256_interrupt; chip->mixer_status_offset = NM_MIXER_STATUS_OFFSET; chip->mixer_status_mask = NM_MIXER_READY_MASK; } else { /* Not sure if there is any relevant detect for the ZX or not. */ if (snd_nm256_readb(chip, 0xa0b) != 0) chip->buffer_end = 6144 * 1024; else chip->buffer_end = 4096 * 1024; chip->interrupt = snd_nm256_interrupt_zx; chip->mixer_status_offset = NM2_MIXER_STATUS_OFFSET; chip->mixer_status_mask = NM2_MIXER_READY_MASK; } chip->buffer_size = chip->streams[SNDRV_PCM_STREAM_PLAYBACK].bufsize + chip->streams[SNDRV_PCM_STREAM_CAPTURE].bufsize; if (chip->use_cache) chip->buffer_size += NM_TOTAL_COEFF_COUNT * 4; else chip->buffer_size += NM_MAX_PLAYBACK_COEF_SIZE + NM_MAX_RECORD_COEF_SIZE; if (buffer_top >= chip->buffer_size && buffer_top < chip->buffer_end) chip->buffer_end = buffer_top; else { /* get buffer end pointer from signature */ if ((err = snd_nm256_peek_for_sig(chip)) < 0) goto __error; } chip->buffer_start = chip->buffer_end - chip->buffer_size; chip->buffer_addr += chip->buffer_start; printk(KERN_INFO "nm256: Mapping port 1 from 0x%x - 0x%x\n", chip->buffer_start, chip->buffer_end); chip->res_buffer = request_mem_region(chip->buffer_addr, chip->buffer_size, card->driver); if (chip->res_buffer == NULL) { snd_printk(KERN_ERR "nm256: buffer 0x%lx (size 0x%x) busy\n", chip->buffer_addr, chip->buffer_size); err = -EBUSY; goto __error; } chip->buffer = ioremap_nocache(chip->buffer_addr, chip->buffer_size); if (chip->buffer == NULL) { err = -ENOMEM; snd_printk(KERN_ERR "unable to map ring buffer at %lx\n", chip->buffer_addr); goto __error; } /* set offsets */ addr = chip->buffer_start; chip->streams[SNDRV_PCM_STREAM_PLAYBACK].buf = addr; addr += chip->streams[SNDRV_PCM_STREAM_PLAYBACK].bufsize; chip->streams[SNDRV_PCM_STREAM_CAPTURE].buf = addr; addr += chip->streams[SNDRV_PCM_STREAM_CAPTURE].bufsize; if (chip->use_cache) { chip->all_coeff_buf = addr; } else { chip->coeff_buf[SNDRV_PCM_STREAM_PLAYBACK] = addr; addr += NM_MAX_PLAYBACK_COEF_SIZE; chip->coeff_buf[SNDRV_PCM_STREAM_CAPTURE] = addr; } /* Fixed setting. */ chip->mixer_base = NM_MIXER_OFFSET; chip->coeffs_current = 0; snd_nm256_init_chip(chip); // pci_set_master(pci); /* needed? */ if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) goto __error; snd_card_set_dev(card, &pci->dev); *chip_ret = chip; return 0; __error: snd_nm256_free(chip); return err; }
static int __devinit snd_nm256_create(struct snd_card *card, struct pci_dev *pci, struct nm256 **chip_ret) { struct nm256 *chip; int err, pval; static struct snd_device_ops ops = { .dev_free = snd_nm256_dev_free, }; u32 addr; *chip_ret = NULL; if ((err = pci_enable_device(pci)) < 0) return err; chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) { pci_disable_device(pci); return -ENOMEM; } chip->card = card; chip->pci = pci; chip->use_cache = use_cache; spin_lock_init(&chip->reg_lock); chip->irq = -1; mutex_init(&chip->irq_mutex); chip->streams[SNDRV_PCM_STREAM_PLAYBACK].bufsize = playback_bufsize * 1024; chip->streams[SNDRV_PCM_STREAM_CAPTURE].bufsize = capture_bufsize * 1024; chip->buffer_addr = pci_resource_start(pci, 0); chip->cport_addr = pci_resource_start(pci, 1); chip->res_cport = request_mem_region(chip->cport_addr, NM_PORT2_SIZE, card->driver); if (chip->res_cport == NULL) { snd_printk(KERN_ERR "memory region 0x%lx (size 0x%x) busy\n", chip->cport_addr, NM_PORT2_SIZE); err = -EBUSY; goto __error; } chip->cport = ioremap_nocache(chip->cport_addr, NM_PORT2_SIZE); if (chip->cport == NULL) { snd_printk(KERN_ERR "unable to map control port %lx\n", chip->cport_addr); err = -ENOMEM; goto __error; } if (!strcmp(card->driver, "NM256AV")) { pval = snd_nm256_readw(chip, NM_MIXER_PRESENCE); if ((pval & NM_PRESENCE_MASK) != NM_PRESENCE_VALUE) { if (! force_ac97) { printk(KERN_ERR "nm256: no ac97 is found!\n"); printk(KERN_ERR " force the driver to load by " "passing in the module parameter\n"); printk(KERN_ERR " force_ac97=1\n"); printk(KERN_ERR " or try sb16, opl3sa2, or " "cs423x drivers instead.\n"); err = -ENXIO; goto __error; } } chip->buffer_end = 2560 * 1024; chip->interrupt = snd_nm256_interrupt; chip->mixer_status_offset = NM_MIXER_STATUS_OFFSET; chip->mixer_status_mask = NM_MIXER_READY_MASK; } else { if (snd_nm256_readb(chip, 0xa0b) != 0) chip->buffer_end = 6144 * 1024; else chip->buffer_end = 4096 * 1024; chip->interrupt = snd_nm256_interrupt_zx; chip->mixer_status_offset = NM2_MIXER_STATUS_OFFSET; chip->mixer_status_mask = NM2_MIXER_READY_MASK; } chip->buffer_size = chip->streams[SNDRV_PCM_STREAM_PLAYBACK].bufsize + chip->streams[SNDRV_PCM_STREAM_CAPTURE].bufsize; if (chip->use_cache) chip->buffer_size += NM_TOTAL_COEFF_COUNT * 4; else chip->buffer_size += NM_MAX_PLAYBACK_COEF_SIZE + NM_MAX_RECORD_COEF_SIZE; if (buffer_top >= chip->buffer_size && buffer_top < chip->buffer_end) chip->buffer_end = buffer_top; else { if ((err = snd_nm256_peek_for_sig(chip)) < 0) goto __error; } chip->buffer_start = chip->buffer_end - chip->buffer_size; chip->buffer_addr += chip->buffer_start; printk(KERN_INFO "nm256: Mapping port 1 from 0x%x - 0x%x\n", chip->buffer_start, chip->buffer_end); chip->res_buffer = request_mem_region(chip->buffer_addr, chip->buffer_size, card->driver); if (chip->res_buffer == NULL) { snd_printk(KERN_ERR "nm256: buffer 0x%lx (size 0x%x) busy\n", chip->buffer_addr, chip->buffer_size); err = -EBUSY; goto __error; } chip->buffer = ioremap_nocache(chip->buffer_addr, chip->buffer_size); if (chip->buffer == NULL) { err = -ENOMEM; snd_printk(KERN_ERR "unable to map ring buffer at %lx\n", chip->buffer_addr); goto __error; } addr = chip->buffer_start; chip->streams[SNDRV_PCM_STREAM_PLAYBACK].buf = addr; addr += chip->streams[SNDRV_PCM_STREAM_PLAYBACK].bufsize; chip->streams[SNDRV_PCM_STREAM_CAPTURE].buf = addr; addr += chip->streams[SNDRV_PCM_STREAM_CAPTURE].bufsize; if (chip->use_cache) { chip->all_coeff_buf = addr; } else { chip->coeff_buf[SNDRV_PCM_STREAM_PLAYBACK] = addr; addr += NM_MAX_PLAYBACK_COEF_SIZE; chip->coeff_buf[SNDRV_PCM_STREAM_CAPTURE] = addr; } chip->mixer_base = NM_MIXER_OFFSET; chip->coeffs_current = 0; snd_nm256_init_chip(chip); if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) goto __error; snd_card_set_dev(card, &pci->dev); *chip_ret = chip; return 0; __error: snd_nm256_free(chip); return err; }