27 #include <linux/module.h>
29 #include <linux/device.h>
33 #include <linux/pci.h>
34 #include <linux/slab.h>
36 #include <asm/delay.h>
48 #define dprintk(level,fmt, arg...) if (debug >= level) \
49 printk(KERN_INFO "%s/1: " fmt, chip->core->name , ## arg)
51 #define dprintk_core(level,fmt, arg...) if (debug >= level) \
52 printk(KERN_DEBUG "%s/1: " fmt, chip->core->name , ## arg)
120 "{{Conexant,23883}");
121 static unsigned int debug;
152 dprintk(1,
"Start audio DMA, %d B/line, %d lines/FIFO, %d periods, %d "
182 dprintk(1,
"Stopping audio DMA\n");
198 #define MAX_IRQ_LOOP 50
203 static const char *cx88_aud_irqs[32] = {
204 "dn_risci1",
"up_risci1",
"rds_dn_risc1",
206 "dn_risci2",
"up_risci2",
"rds_dn_risc2",
208 "dnf_of",
"upf_uf",
"rds_dnf_uf",
210 "dn_sync",
"up_sync",
"rds_dn_sync",
212 "opc_err",
"par_err",
"rip_err",
213 "pci_abort",
"ber_irq",
"mchg_irq"
226 if (0 == (status & mask))
229 if (debug > 1 || (status & mask & ~0xff))
240 dprintk(1,
"Downstream sync error\n");
260 int loop, handled = 0;
267 dprintk(3,
"cx8801_irq loop %d/%d, status %x\n",
268 loop, MAX_IRQ_LOOP, status);
275 cx8801_aud_irq(chip);
278 if (MAX_IRQ_LOOP == loop) {
280 "%s/1: IRQ loop detected, disabling interrupts\n",
313 #define DEFAULT_FIFO_SIZE 4096
332 .buffer_bytes_max = (1024*1024),
346 " Can't proceed with open\n");
356 runtime->
hw = snd_cx88_digital_hw;
361 runtime->
hw.period_bytes_min = bpl;
362 runtime->
hw.period_bytes_max = bpl;
367 dprintk(1,
"Error opening PCM!\n");
391 if (substream->
runtime->dma_area) {
392 dsp_buffer_free(chip);
396 chip->
period_size = params_period_bytes(hw_params);
434 substream->
runtime->dma_addr = 0;
450 if (substream->
runtime->dma_area) {
451 dsp_buffer_free(chip);
479 err=_cx88_start_audio_dma(chip);
482 err=_cx88_stop_audio_dma(chip);
525 .
open = snd_cx88_pcm_open,
526 .close = snd_cx88_close,
528 .hw_params = snd_cx88_hw_params,
529 .hw_free = snd_cx88_hw_free,
530 .prepare = snd_cx88_prepare,
531 .trigger = snd_cx88_card_trigger,
532 .pointer = snd_cx88_pointer,
533 .page = snd_cx88_page,
557 static int snd_cx88_volume_info(
struct snd_kcontrol *kcontrol,
568 static int snd_cx88_volume_get(
struct snd_kcontrol *kcontrol,
576 value->
value.integer.value[(bal & 0x40) ? 0 : 1] = vol;
578 value->
value.integer.value[(bal & 0x40) ? 1 : 0] = vol < 0 ? 0 : vol;
583 static void snd_cx88_wm8775_volume_put(
struct snd_kcontrol *kcontrol,
588 int left = value->
value.integer.value[0];
595 b = left ? (0x8000 *
right) / left : 0x8000;
598 b = right ? 0xffff - (0x8000 *
left) / right : 0x8000;
605 static int snd_cx88_volume_put(
struct snd_kcontrol *kcontrol,
615 snd_cx88_wm8775_volume_put(kcontrol, value);
617 left = value->
value.integer.value[0] & 0x3f;
618 right = value->
value.integer.value[1] & 0x3f;
629 if (v != (old & 0x3f)) {
648 .name =
"Analog-TV Volume",
649 .info = snd_cx88_volume_info,
650 .get = snd_cx88_volume_get,
651 .put = snd_cx88_volume_put,
652 .tlv.p = snd_cx88_db_scale,
655 static int snd_cx88_switch_get(
struct snd_kcontrol *kcontrol,
666 static int snd_cx88_switch_put(
struct snd_kcontrol *kcontrol,
677 if (value->
value.integer.value[0] != !(vol & bit)) {
692 .name =
"Audio-Out Switch",
694 .get = snd_cx88_switch_get,
695 .put = snd_cx88_switch_put,
696 .private_value = (1<<8),
701 .name =
"Analog-TV Switch",
703 .get = snd_cx88_switch_get,
704 .put = snd_cx88_switch_put,
705 .private_value = (1<<6),
708 static int snd_cx88_alc_get(
struct snd_kcontrol *kcontrol,
716 value->
value.integer.value[0] = val ? 1 : 0;
720 static int snd_cx88_alc_put(
struct snd_kcontrol *kcontrol,
727 memset(&client_ctl, 0,
sizeof(client_ctl));
728 client_ctl.
value = 0 != value->
value.integer.value[0];
737 .name =
"Line-In ALC Switch",
739 .get = snd_cx88_alc_get,
740 .put = snd_cx88_alc_put,
752 static const struct pci_device_id cx88_audio_pci_tbl[] __devinitdata = {
799 unsigned char pci_lat;
818 dprintk(0,
"%s/1: Oops: no 32bit PCI DMA ???\n",core->
name);
837 dprintk(0,
"%s: can't get IRQ %d\n",
838 chip->
core->name, chip->
pci->irq);
845 dprintk(1,
"ALSA %s/%i: found at %s, rev: %d, irq: %d, "
846 "latency: %d, mmio: 0x%llx\n", core->
name, devno,
884 err = snd_cx88_create(card, pci, &chip, &core);
888 err = snd_cx88_pcm(chip, 0,
"CX88 Digital");
912 dprintk (0,
"%s/%i: ALSA support for cx2388x boards\n",
918 pci_set_drvdata(pci,card);
936 pci_set_drvdata(pci,
NULL);
945 static struct pci_driver cx88_audio_pci_driver = {
946 .
name =
"cx88_audio",
947 .id_table = cx88_audio_pci_tbl,
948 .probe = cx88_audio_initdev,
959 static int __init cx88_audio_init(
void)
963 return pci_register_driver(&cx88_audio_pci_driver);
969 static void __exit cx88_audio_fini(
void)