Commit 79dd0c69 authored by Ricardo Cerqueira's avatar Ricardo Cerqueira Committed by Linus Torvalds

[PATCH] V4L: 925: saa7134 alsa is now a standalone module

Saa7134-alsa is now a standalone module
Signed-off-by: default avatarRicardo Cerqueira <v4l@cerqueira.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@brturbo.com.br>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 875c296b
/* /*
* SAA713x ALSA support for V4L * SAA713x ALSA support for V4L
* Ricardo Cerqueira <v4l@cerqueira.org>
* *
* *
* Caveats: * Caveats:
...@@ -37,9 +36,13 @@ ...@@ -37,9 +36,13 @@
#include "saa7134.h" #include "saa7134.h"
#include "saa7134-reg.h" #include "saa7134-reg.h"
static unsigned int alsa_debug = 0; static unsigned int debug = 0;
module_param(alsa_debug, int, 0644); module_param(debug, int, 0644);
MODULE_PARM_DESC(alsa_debug,"enable debug messages [alsa]"); MODULE_PARM_DESC(debug,"enable debug messages [alsa]");
unsigned int dsp_nr = 0;
module_param(dsp_nr, int, 0444);
MODULE_PARM_DESC(dsp_nr, "alsa device number");
/* /*
* Configuration macros * Configuration macros
...@@ -69,7 +72,7 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ ...@@ -69,7 +72,7 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0}; static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
#define dprintk(fmt, arg...) if (alsa_debug) \ #define dprintk(fmt, arg...) if (debug) \
printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ## arg) printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ## arg)
/* /*
...@@ -107,6 +110,7 @@ typedef struct snd_card_saa7134_pcm { ...@@ -107,6 +110,7 @@ typedef struct snd_card_saa7134_pcm {
static snd_card_t *snd_saa7134_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; static snd_card_t *snd_saa7134_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
/* /*
* saa7134 DMA audio stop * saa7134 DMA audio stop
* *
...@@ -189,12 +193,11 @@ void saa7134_irq_alsa_done(struct saa7134_dev *dev, unsigned long status) ...@@ -189,12 +193,11 @@ void saa7134_irq_alsa_done(struct saa7134_dev *dev, unsigned long status)
/* next block addr */ /* next block addr */
next_blk = (dev->oss.dma_blk + 2) % dev->oss.blocks; next_blk = (dev->oss.dma_blk + 2) % dev->oss.blocks;
saa_writel(reg,next_blk * dev->oss.blksize); saa_writel(reg,next_blk * dev->oss.blksize);
if (alsa_debug > 2) if (debug > 2)
dprintk("irq: ok, %s, next_blk=%d, addr=%x, blocks=%u, size=%u, read=%u\n", dprintk("irq: ok, %s, next_blk=%d, addr=%x, blocks=%u, size=%u, read=%u\n",
(status & 0x10000000) ? "even" : "odd ", next_blk, (status & 0x10000000) ? "even" : "odd ", next_blk,
next_blk * dev->oss.blksize, dev->oss.blocks, dev->oss.blksize, dev->oss.read_count); next_blk * dev->oss.blksize, dev->oss.blocks, dev->oss.blksize, dev->oss.read_count);
/* update status & wake waiting readers */ /* update status & wake waiting readers */
dev->oss.dma_blk = (dev->oss.dma_blk + 1) % dev->oss.blocks; dev->oss.dma_blk = (dev->oss.dma_blk + 1) % dev->oss.blocks;
dev->oss.read_count += dev->oss.blksize; dev->oss.read_count += dev->oss.blksize;
...@@ -211,6 +214,41 @@ void saa7134_irq_alsa_done(struct saa7134_dev *dev, unsigned long status) ...@@ -211,6 +214,41 @@ void saa7134_irq_alsa_done(struct saa7134_dev *dev, unsigned long status)
} }
/*
* IRQ request handler
*
* Runs along with saa7134's IRQ handler, discards anything that isn't
* DMA sound
*
*/
static irqreturn_t saa7134_alsa_irq(int irq, void *dev_id, struct pt_regs *regs)
{
struct saa7134_dev *dev = (struct saa7134_dev*) dev_id;
unsigned long report, status;
int loop, handled = 0;
for (loop = 0; loop < 10; loop++) {
report = saa_readl(SAA7134_IRQ_REPORT);
status = saa_readl(SAA7134_IRQ_STATUS);
if (report & SAA7134_IRQ_REPORT_DONE_RA3) {
handled = 1;
saa_writel(SAA7134_IRQ_REPORT,report);
saa7134_irq_alsa_done(dev, status);
} else {
goto out;
}
}
if (loop == 10) {
dprintk("error! looping IRQ!");
}
out:
return IRQ_RETVAL(handled);
}
/* /*
* ALSA capture trigger * ALSA capture trigger
* *
...@@ -822,11 +860,9 @@ static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_ ...@@ -822,11 +860,9 @@ static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
saa_dsp_writel(dev, SAA7133_DIGITAL_OUTPUT_SEL1, 0xbbbb10); saa_dsp_writel(dev, SAA7133_DIGITAL_OUTPUT_SEL1, 0xbbbb10);
if (left || right) { // We've got data, turn the input on if (left || right) { // We've got data, turn the input on
//saa_dsp_writel(dev, SAA7133_DIGITAL_OUTPUT_SEL2, 0x101010);
saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1, xbarin); saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1, xbarin);
saa_writel(SAA7133_ANALOG_IO_SELECT, anabar); saa_writel(SAA7133_ANALOG_IO_SELECT, anabar);
} else { } else {
//saa_dsp_writel(dev, SAA7133_DIGITAL_OUTPUT_SEL2, 0x101010);
saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1, 0); saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1, 0);
saa_writel(SAA7133_ANALOG_IO_SELECT, 0); saa_writel(SAA7133_ANALOG_IO_SELECT, 0);
} }
...@@ -889,9 +925,10 @@ static int snd_saa7134_dev_free(snd_device_t *device) ...@@ -889,9 +925,10 @@ static int snd_saa7134_dev_free(snd_device_t *device)
* *
*/ */
int alsa_card_saa7134_create(struct saa7134_dev *saadev, unsigned int devicenum) int alsa_card_saa7134_create (struct saa7134_dev *saadev, unsigned int devicenum)
{ {
static int dev; static int dev;
snd_card_t *card; snd_card_t *card;
snd_card_saa7134_t *chip; snd_card_saa7134_t *chip;
int err; int err;
...@@ -899,6 +936,7 @@ int alsa_card_saa7134_create(struct saa7134_dev *saadev, unsigned int devicenum) ...@@ -899,6 +936,7 @@ int alsa_card_saa7134_create(struct saa7134_dev *saadev, unsigned int devicenum)
.dev_free = snd_saa7134_dev_free, .dev_free = snd_saa7134_dev_free,
}; };
if (dev >= SNDRV_CARDS) if (dev >= SNDRV_CARDS)
return -ENODEV; return -ENODEV;
if (!enable[dev]) if (!enable[dev])
...@@ -906,6 +944,7 @@ int alsa_card_saa7134_create(struct saa7134_dev *saadev, unsigned int devicenum) ...@@ -906,6 +944,7 @@ int alsa_card_saa7134_create(struct saa7134_dev *saadev, unsigned int devicenum)
if (devicenum) { if (devicenum) {
card = snd_card_new(devicenum, id[dev], THIS_MODULE, 0); card = snd_card_new(devicenum, id[dev], THIS_MODULE, 0);
dsp_nr++;
} else { } else {
card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
} }
...@@ -931,6 +970,15 @@ int alsa_card_saa7134_create(struct saa7134_dev *saadev, unsigned int devicenum) ...@@ -931,6 +970,15 @@ int alsa_card_saa7134_create(struct saa7134_dev *saadev, unsigned int devicenum)
chip->irq = saadev->pci->irq; chip->irq = saadev->pci->irq;
chip->iobase = pci_resource_start(saadev->pci, 0); chip->iobase = pci_resource_start(saadev->pci, 0);
err = request_irq(chip->pci->irq, saa7134_alsa_irq,
SA_SHIRQ | SA_INTERRUPT, saadev->name, saadev);
if (err < 0) {
printk(KERN_ERR "%s: can't get IRQ %d for ALSA\n",
saadev->name, saadev->pci->irq);
return err;
}
if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
snd_saa7134_free(chip); snd_saa7134_free(chip);
return err; return err;
...@@ -963,10 +1011,48 @@ int alsa_card_saa7134_create(struct saa7134_dev *saadev, unsigned int devicenum) ...@@ -963,10 +1011,48 @@ int alsa_card_saa7134_create(struct saa7134_dev *saadev, unsigned int devicenum)
return err; return err;
} }
void alsa_card_saa7134_exit(void) /*
* Module initializer
*
* Loops through present saa7134 cards, and assigns an ALSA device
* to each one
*
*/
static int saa7134_alsa_init(void)
{
struct saa7134_dev *saadev = NULL;
struct list_head *list;
printk(KERN_INFO "saa7134 ALSA driver for DMA sound loaded\n");
list_for_each(list,&saa7134_devlist) {
saadev = list_entry(list, struct saa7134_dev, devlist);
alsa_card_saa7134_create(saadev,dsp_nr);
}
if (saadev == NULL)
printk(KERN_INFO "saa7134 ALSA: no saa7134 cards found\n");
return 0;
}
/*
* Module destructor
*/
void saa7134_alsa_exit(void)
{ {
int idx; int idx;
for (idx = 0; idx < SNDRV_CARDS; idx++) { for (idx = 0; idx < SNDRV_CARDS; idx++) {
snd_card_free(snd_saa7134_cards[idx]); snd_card_free(snd_saa7134_cards[idx]);
} }
printk(KERN_INFO "saa7134 ALSA driver for DMA sound unloaded\n");
return;
} }
module_init(saa7134_alsa_init);
module_exit(saa7134_alsa_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Ricardo Cerqueira");
...@@ -574,6 +574,17 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs) ...@@ -574,6 +574,17 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
dev->name); dev->name);
goto out; goto out;
} }
/* If alsa support is active and we get a sound report, exit
and let the saa7134-alsa module deal with it */
if ((report & SAA7134_IRQ_REPORT_DONE_RA3) && alsa) {
if (irq_debug > 1)
printk(KERN_DEBUG "%s/irq: ignoring interrupt for ALSA\n",
dev->name);
goto out;
}
handled = 1; handled = 1;
saa_writel(SAA7134_IRQ_REPORT,report); saa_writel(SAA7134_IRQ_REPORT,report);
if (irq_debug) if (irq_debug)
...@@ -598,8 +609,6 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs) ...@@ -598,8 +609,6 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
if ((report & SAA7134_IRQ_REPORT_DONE_RA3)) { if ((report & SAA7134_IRQ_REPORT_DONE_RA3)) {
if (oss) { if (oss) {
saa7134_irq_oss_done(dev,status); saa7134_irq_oss_done(dev,status);
} else if (alsa) {
saa7134_irq_alsa_done(dev,status);
} }
} }
...@@ -1029,9 +1038,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, ...@@ -1029,9 +1038,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
printk(KERN_INFO "%s: registered device mixer%d\n", printk(KERN_INFO "%s: registered device mixer%d\n",
dev->name,dev->oss.minor_mixer >> 4); dev->name,dev->oss.minor_mixer >> 4);
} else if (alsa) { } else if (alsa) {
alsa_card_saa7134_create(dev,dsp_nr[dev->nr]); request_module("saa7134-alsa");
printk(KERN_INFO "%s: registered ALSA devices\n",
dev->name);
} }
break; break;
} }
...@@ -1059,8 +1066,6 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, ...@@ -1059,8 +1066,6 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
case PCI_DEVICE_ID_PHILIPS_SAA7135: case PCI_DEVICE_ID_PHILIPS_SAA7135:
if (oss) if (oss)
unregister_sound_dsp(dev->oss.minor_dsp); unregister_sound_dsp(dev->oss.minor_dsp);
else if (alsa)
alsa_card_saa7134_exit();
break; break;
} }
fail4: fail4:
...@@ -1120,8 +1125,7 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev) ...@@ -1120,8 +1125,7 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
if (oss) { if (oss) {
unregister_sound_mixer(dev->oss.minor_mixer); unregister_sound_mixer(dev->oss.minor_mixer);
unregister_sound_dsp(dev->oss.minor_dsp); unregister_sound_dsp(dev->oss.minor_dsp);
} else if (alsa) }
alsa_card_saa7134_exit();
break; break;
} }
saa7134_unregister_video(dev); saa7134_unregister_video(dev);
...@@ -1214,6 +1218,13 @@ EXPORT_SYMBOL(saa7134_i2c_call_clients); ...@@ -1214,6 +1218,13 @@ EXPORT_SYMBOL(saa7134_i2c_call_clients);
EXPORT_SYMBOL(saa7134_devlist); EXPORT_SYMBOL(saa7134_devlist);
EXPORT_SYMBOL(saa7134_boards); EXPORT_SYMBOL(saa7134_boards);
/* ----------------- For ALSA -------------------------------- */
EXPORT_SYMBOL(saa7134_pgtable_free);
EXPORT_SYMBOL(saa7134_pgtable_build);
EXPORT_SYMBOL(saa7134_pgtable_alloc);
EXPORT_SYMBOL(saa7134_set_dmabits);
/* ----------------------------------------------------------- */ /* ----------------------------------------------------------- */
/* /*
* Local variables: * Local variables:
......
...@@ -1024,9 +1024,12 @@ int saa7134_tvaudio_do_scan(struct saa7134_dev *dev) ...@@ -1024,9 +1024,12 @@ int saa7134_tvaudio_do_scan(struct saa7134_dev *dev)
return 0; return 0;
} }
EXPORT_SYMBOL(saa_dsp_writel);
/* ----------------------------------------------------------- */ /* ----------------------------------------------------------- */
/* /*
* Local variables: * Local variables:
* c-basic-offset: 8 * c-basic-offset: 8
* End: * End:
*/ */
...@@ -665,14 +665,6 @@ void saa7134_input_fini(struct saa7134_dev *dev); ...@@ -665,14 +665,6 @@ void saa7134_input_fini(struct saa7134_dev *dev);
void saa7134_input_irq(struct saa7134_dev *dev); void saa7134_input_irq(struct saa7134_dev *dev);
void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir); void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir);
/* ----------------------------------------------------------- */
/* saa7134-alsa.c */
int alsa_card_saa7134_create(struct saa7134_dev *saadev, unsigned int devnum);
void alsa_card_saa7134_exit(void);
void saa7134_irq_alsa_done(struct saa7134_dev *dev, unsigned long status);
/* /*
* Local variables: * Local variables:
* c-basic-offset: 8 * c-basic-offset: 8
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment