Lines Matching +full:flip +full:- +full:chip

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * als300.c - driver for Avance Logic ALS300/ALS300+ soundcards.
16 * This is why we always use 2 periods. We can then use a flip-flop variable
24 #include <linux/dma-mapping.h>
151 static void snd_als300_set_irq_flag(struct snd_als300 *chip, int cmd) in snd_als300_set_irq_flag() argument
153 u32 tmp = snd_als300_gcr_read(chip->port, MISC_CONTROL); in snd_als300_set_irq_flag()
158 if (((chip->revision > 5 || chip->chip_type == DEVICE_ALS300_PLUS) ^ in snd_als300_set_irq_flag()
163 snd_als300_gcr_write(chip->port, MISC_CONTROL, tmp); in snd_als300_set_irq_flag()
168 struct snd_als300 *chip = card->private_data; in snd_als300_free() local
170 snd_als300_set_irq_flag(chip, IRQ_DISABLE); in snd_als300_free()
176 struct snd_als300 *chip = dev_id; in snd_als300_interrupt() local
179 status = inb(chip->port+ALS300_IRQ_STATUS); in snd_als300_interrupt()
184 outb(status, chip->port+ALS300_IRQ_STATUS); in snd_als300_interrupt()
186 if (chip->pcm && chip->playback_substream) { in snd_als300_interrupt()
187 data = chip->playback_substream->runtime->private_data; in snd_als300_interrupt()
188 data->period_flipflop ^= 1; in snd_als300_interrupt()
189 snd_pcm_period_elapsed(chip->playback_substream); in snd_als300_interrupt()
194 if (chip->pcm && chip->capture_substream) { in snd_als300_interrupt()
195 data = chip->capture_substream->runtime->private_data; in snd_als300_interrupt()
196 data->period_flipflop ^= 1; in snd_als300_interrupt()
197 snd_pcm_period_elapsed(chip->capture_substream); in snd_als300_interrupt()
207 struct snd_als300 *chip = dev_id; in snd_als300plus_interrupt() local
210 general = inb(chip->port+ALS300P_IRQ_STATUS); in snd_als300plus_interrupt()
211 mpu = inb(chip->port+MPU_IRQ_STATUS); in snd_als300plus_interrupt()
212 dram = inb(chip->port+ALS300P_DRAM_IRQ_STATUS); in snd_als300plus_interrupt()
219 if (chip->pcm && chip->playback_substream) { in snd_als300plus_interrupt()
220 outb(IRQ_PLAYBACK, chip->port+ALS300P_IRQ_STATUS); in snd_als300plus_interrupt()
221 data = chip->playback_substream->runtime->private_data; in snd_als300plus_interrupt()
222 data->period_flipflop ^= 1; in snd_als300plus_interrupt()
223 snd_pcm_period_elapsed(chip->playback_substream); in snd_als300plus_interrupt()
228 if (chip->pcm && chip->capture_substream) { in snd_als300plus_interrupt()
229 outb(IRQ_CAPTURE, chip->port+ALS300P_IRQ_STATUS); in snd_als300plus_interrupt()
230 data = chip->capture_substream->runtime->private_data; in snd_als300plus_interrupt()
231 data->period_flipflop ^= 1; in snd_als300plus_interrupt()
232 snd_pcm_period_elapsed(chip->capture_substream); in snd_als300plus_interrupt()
245 struct snd_als300 *chip = ac97->private_data; in snd_als300_ac97_read() local
248 if ((inb(chip->port+AC97_STATUS) & (AC97_BUSY)) == 0) in snd_als300_ac97_read()
252 outl((reg << 24) | (1 << 31), chip->port+AC97_ACCESS); in snd_als300_ac97_read()
255 if ((inb(chip->port+AC97_STATUS) & (AC97_DATA_AVAIL)) != 0) in snd_als300_ac97_read()
259 return inw(chip->port+AC97_READ); in snd_als300_ac97_read()
266 struct snd_als300 *chip = ac97->private_data; in snd_als300_ac97_write() local
269 if ((inb(chip->port+AC97_STATUS) & (AC97_BUSY)) == 0) in snd_als300_ac97_write()
273 outl((reg << 24) | val, chip->port+AC97_ACCESS); in snd_als300_ac97_write()
276 static int snd_als300_ac97(struct snd_als300 *chip) in snd_als300_ac97() argument
286 err = snd_ac97_bus(chip->card, 0, &ops, NULL, &bus); in snd_als300_ac97()
291 ac97.private_data = chip; in snd_als300_ac97()
293 return snd_ac97_mixer(bus, &ac97, &chip->ac97); in snd_als300_ac97()
343 struct snd_als300 *chip = snd_pcm_substream_chip(substream); in snd_als300_playback_open() local
344 struct snd_pcm_runtime *runtime = substream->runtime; in snd_als300_playback_open()
349 return -ENOMEM; in snd_als300_playback_open()
350 chip->playback_substream = substream; in snd_als300_playback_open()
351 runtime->hw = snd_als300_playback_hw; in snd_als300_playback_open()
352 runtime->private_data = data; in snd_als300_playback_open()
353 data->control_register = PLAYBACK_CONTROL; in snd_als300_playback_open()
354 data->block_counter_register = PLAYBACK_BLOCK_COUNTER; in snd_als300_playback_open()
360 struct snd_als300 *chip = snd_pcm_substream_chip(substream); in snd_als300_playback_close() local
363 data = substream->runtime->private_data; in snd_als300_playback_close()
365 chip->playback_substream = NULL; in snd_als300_playback_close()
371 struct snd_als300 *chip = snd_pcm_substream_chip(substream); in snd_als300_capture_open() local
372 struct snd_pcm_runtime *runtime = substream->runtime; in snd_als300_capture_open()
377 return -ENOMEM; in snd_als300_capture_open()
378 chip->capture_substream = substream; in snd_als300_capture_open()
379 runtime->hw = snd_als300_capture_hw; in snd_als300_capture_open()
380 runtime->private_data = data; in snd_als300_capture_open()
381 data->control_register = RECORD_CONTROL; in snd_als300_capture_open()
382 data->block_counter_register = RECORD_BLOCK_COUNTER; in snd_als300_capture_open()
388 struct snd_als300 *chip = snd_pcm_substream_chip(substream); in snd_als300_capture_close() local
391 data = substream->runtime->private_data; in snd_als300_capture_close()
393 chip->capture_substream = NULL; in snd_als300_capture_close()
400 struct snd_als300 *chip = snd_pcm_substream_chip(substream); in snd_als300_playback_prepare() local
401 struct snd_pcm_runtime *runtime = substream->runtime; in snd_als300_playback_prepare()
405 spin_lock_irq(&chip->reg_lock); in snd_als300_playback_prepare()
406 tmp = snd_als300_gcr_read(chip->port, PLAYBACK_CONTROL); in snd_als300_playback_prepare()
414 tmp |= period_bytes - 1; in snd_als300_playback_prepare()
415 snd_als300_gcr_write(chip->port, PLAYBACK_CONTROL, tmp); in snd_als300_playback_prepare()
418 snd_als300_gcr_write(chip->port, PLAYBACK_START, in snd_als300_playback_prepare()
419 runtime->dma_addr); in snd_als300_playback_prepare()
420 snd_als300_gcr_write(chip->port, PLAYBACK_END, in snd_als300_playback_prepare()
421 runtime->dma_addr + buffer_bytes - 1); in snd_als300_playback_prepare()
422 spin_unlock_irq(&chip->reg_lock); in snd_als300_playback_prepare()
429 struct snd_als300 *chip = snd_pcm_substream_chip(substream); in snd_als300_capture_prepare() local
430 struct snd_pcm_runtime *runtime = substream->runtime; in snd_als300_capture_prepare()
434 spin_lock_irq(&chip->reg_lock); in snd_als300_capture_prepare()
435 tmp = snd_als300_gcr_read(chip->port, RECORD_CONTROL); in snd_als300_capture_prepare()
443 tmp |= period_bytes - 1; in snd_als300_capture_prepare()
446 snd_als300_gcr_write(chip->port, RECORD_CONTROL, tmp); in snd_als300_capture_prepare()
447 snd_als300_gcr_write(chip->port, RECORD_START, in snd_als300_capture_prepare()
448 runtime->dma_addr); in snd_als300_capture_prepare()
449 snd_als300_gcr_write(chip->port, RECORD_END, in snd_als300_capture_prepare()
450 runtime->dma_addr + buffer_bytes - 1); in snd_als300_capture_prepare()
451 spin_unlock_irq(&chip->reg_lock); in snd_als300_capture_prepare()
457 struct snd_als300 *chip = snd_pcm_substream_chip(substream); in snd_als300_trigger() local
463 data = substream->runtime->private_data; in snd_als300_trigger()
464 reg = data->control_register; in snd_als300_trigger()
466 spin_lock(&chip->reg_lock); in snd_als300_trigger()
470 tmp = snd_als300_gcr_read(chip->port, reg); in snd_als300_trigger()
471 data->period_flipflop = 1; in snd_als300_trigger()
472 snd_als300_gcr_write(chip->port, reg, tmp | TRANSFER_START); in snd_als300_trigger()
477 tmp = snd_als300_gcr_read(chip->port, reg); in snd_als300_trigger()
478 snd_als300_gcr_write(chip->port, reg, tmp & ~TRANSFER_START); in snd_als300_trigger()
482 tmp = snd_als300_gcr_read(chip->port, reg); in snd_als300_trigger()
483 snd_als300_gcr_write(chip->port, reg, tmp | FIFO_PAUSE); in snd_als300_trigger()
487 tmp = snd_als300_gcr_read(chip->port, reg); in snd_als300_trigger()
488 snd_als300_gcr_write(chip->port, reg, tmp & ~FIFO_PAUSE); in snd_als300_trigger()
493 ret = -EINVAL; in snd_als300_trigger()
495 spin_unlock(&chip->reg_lock); in snd_als300_trigger()
502 struct snd_als300 *chip = snd_pcm_substream_chip(substream); in snd_als300_pointer() local
506 data = substream->runtime->private_data; in snd_als300_pointer()
509 spin_lock(&chip->reg_lock); in snd_als300_pointer()
510 current_ptr = (u16) snd_als300_gcr_read(chip->port, in snd_als300_pointer()
511 data->block_counter_register) + 4; in snd_als300_pointer()
512 spin_unlock(&chip->reg_lock); in snd_als300_pointer()
516 current_ptr = period_bytes - current_ptr; in snd_als300_pointer()
518 if (data->period_flipflop == 0) in snd_als300_pointer()
521 return bytes_to_frames(substream->runtime, current_ptr); in snd_als300_pointer()
540 static int snd_als300_new_pcm(struct snd_als300 *chip) in snd_als300_new_pcm() argument
545 err = snd_pcm_new(chip->card, "ALS300", 0, 1, 1, &pcm); in snd_als300_new_pcm()
548 pcm->private_data = chip; in snd_als300_new_pcm()
549 strcpy(pcm->name, "ALS300"); in snd_als300_new_pcm()
550 chip->pcm = pcm; in snd_als300_new_pcm()
558 /* pre-allocation of buffers */ in snd_als300_new_pcm()
559 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, &chip->pci->dev, in snd_als300_new_pcm()
564 static void snd_als300_init(struct snd_als300 *chip) in snd_als300_init() argument
569 spin_lock_irqsave(&chip->reg_lock, flags); in snd_als300_init()
570 chip->revision = (snd_als300_gcr_read(chip->port, MISC_CONTROL) >> 16) in snd_als300_init()
573 tmp = snd_als300_gcr_read(chip->port, DRAM_WRITE_CONTROL); in snd_als300_init()
574 snd_als300_gcr_write(chip->port, DRAM_WRITE_CONTROL, in snd_als300_init()
579 snd_als300_set_irq_flag(chip, IRQ_ENABLE); in snd_als300_init()
583 tmp = snd_als300_gcr_read(chip->port, MISC_CONTROL); in snd_als300_init()
584 snd_als300_gcr_write(chip->port, MISC_CONTROL, in snd_als300_init()
588 snd_als300_gcr_write(chip->port, MUS_VOC_VOL, 0); in snd_als300_init()
591 tmp = snd_als300_gcr_read(chip->port, PLAYBACK_CONTROL); in snd_als300_init()
592 snd_als300_gcr_write(chip->port, PLAYBACK_CONTROL, in snd_als300_init()
594 spin_unlock_irqrestore(&chip->reg_lock, flags); in snd_als300_init()
600 struct snd_als300 *chip = card->private_data; in snd_als300_create() local
608 if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(28))) { in snd_als300_create()
609 dev_err(card->dev, "error setting 28bit DMA mask\n"); in snd_als300_create()
610 return -ENXIO; in snd_als300_create()
614 chip->card = card; in snd_als300_create()
615 chip->pci = pci; in snd_als300_create()
616 chip->irq = -1; in snd_als300_create()
617 chip->chip_type = chip_type; in snd_als300_create()
618 spin_lock_init(&chip->reg_lock); in snd_als300_create()
624 chip->port = pci_resource_start(pci, 0); in snd_als300_create()
626 if (chip->chip_type == DEVICE_ALS300_PLUS) in snd_als300_create()
631 if (devm_request_irq(&pci->dev, pci->irq, irq_handler, IRQF_SHARED, in snd_als300_create()
632 KBUILD_MODNAME, chip)) { in snd_als300_create()
633 dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq); in snd_als300_create()
634 return -EBUSY; in snd_als300_create()
636 chip->irq = pci->irq; in snd_als300_create()
637 card->sync_irq = chip->irq; in snd_als300_create()
638 card->private_free = snd_als300_free; in snd_als300_create()
640 snd_als300_init(chip); in snd_als300_create()
642 err = snd_als300_ac97(chip); in snd_als300_create()
644 dev_err(card->dev, "Could not create ac97\n"); in snd_als300_create()
648 err = snd_als300_new_pcm(chip); in snd_als300_create()
650 dev_err(card->dev, "Could not create PCM\n"); in snd_als300_create()
660 struct snd_als300 *chip = card->private_data; in snd_als300_suspend() local
663 snd_ac97_suspend(chip->ac97); in snd_als300_suspend()
670 struct snd_als300 *chip = card->private_data; in snd_als300_resume() local
672 snd_als300_init(chip); in snd_als300_resume()
673 snd_ac97_resume(chip->ac97); in snd_als300_resume()
686 struct snd_als300 *chip; in snd_als300_probe() local
690 return -ENODEV; in snd_als300_probe()
693 return -ENOENT; in snd_als300_probe()
696 err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, in snd_als300_probe()
697 sizeof(*chip), &card); in snd_als300_probe()
700 chip = card->private_data; in snd_als300_probe()
702 chip_type = pci_id->driver_data; in snd_als300_probe()
708 strcpy(card->driver, "ALS300"); in snd_als300_probe()
709 if (chip->chip_type == DEVICE_ALS300_PLUS) in snd_als300_probe()
712 sprintf(card->shortname, "ALS300+ (Rev. %d)", chip->revision); in snd_als300_probe()
714 sprintf(card->shortname, "ALS300 (Rev. %c)", 'A' + in snd_als300_probe()
715 chip->revision - 1); in snd_als300_probe()
716 sprintf(card->longname, "%s at 0x%lx irq %i", in snd_als300_probe()
717 card->shortname, chip->port, chip->irq); in snd_als300_probe()