diff options
Diffstat (limited to 'drivers/media/video/saa7134/saa7134-alsa.c')
-rw-r--r-- | drivers/media/video/saa7134/saa7134-alsa.c | 484 |
1 files changed, 241 insertions, 243 deletions
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c index 4f3c42354329..ade05f75fdb0 100644 --- a/drivers/media/video/saa7134/saa7134-alsa.c +++ b/drivers/media/video/saa7134/saa7134-alsa.c | |||
@@ -30,7 +30,9 @@ | |||
30 | #include <sound/core.h> | 30 | #include <sound/core.h> |
31 | #include <sound/control.h> | 31 | #include <sound/control.h> |
32 | #include <sound/pcm.h> | 32 | #include <sound/pcm.h> |
33 | #include <sound/pcm_params.h> | ||
33 | #include <sound/initval.h> | 34 | #include <sound/initval.h> |
35 | #include <linux/interrupt.h> | ||
34 | 36 | ||
35 | #include "saa7134.h" | 37 | #include "saa7134.h" |
36 | #include "saa7134-reg.h" | 38 | #include "saa7134-reg.h" |
@@ -49,6 +51,7 @@ MODULE_PARM_DESC(debug,"enable debug messages [alsa]"); | |||
49 | #define MIXER_ADDR_LINE2 2 | 51 | #define MIXER_ADDR_LINE2 2 |
50 | #define MIXER_ADDR_LAST 2 | 52 | #define MIXER_ADDR_LAST 2 |
51 | 53 | ||
54 | |||
52 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ | 55 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ |
53 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ | 56 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ |
54 | static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0}; | 57 | static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0}; |
@@ -57,18 +60,21 @@ module_param_array(index, int, NULL, 0444); | |||
57 | MODULE_PARM_DESC(index, "Index value for SAA7134 capture interface(s)."); | 60 | MODULE_PARM_DESC(index, "Index value for SAA7134 capture interface(s)."); |
58 | 61 | ||
59 | #define dprintk(fmt, arg...) if (debug) \ | 62 | #define dprintk(fmt, arg...) if (debug) \ |
60 | printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ## arg) | 63 | printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ##arg) |
64 | |||
65 | |||
61 | 66 | ||
62 | /* | 67 | /* |
63 | * Main chip structure | 68 | * Main chip structure |
64 | */ | 69 | */ |
70 | |||
65 | typedef struct snd_card_saa7134 { | 71 | typedef struct snd_card_saa7134 { |
66 | snd_card_t *card; | 72 | snd_card_t *card; |
67 | spinlock_t mixer_lock; | 73 | spinlock_t mixer_lock; |
68 | int mixer_volume[MIXER_ADDR_LAST+1][2]; | 74 | int mixer_volume[MIXER_ADDR_LAST+1][2]; |
69 | int capture_source[MIXER_ADDR_LAST+1][2]; | 75 | int capture_source[MIXER_ADDR_LAST+1][2]; |
70 | struct pci_dev *pci; | 76 | struct pci_dev *pci; |
71 | struct saa7134_dev *saadev; | 77 | struct saa7134_dev *dev; |
72 | 78 | ||
73 | unsigned long iobase; | 79 | unsigned long iobase; |
74 | int irq; | 80 | int irq; |
@@ -83,12 +89,10 @@ typedef struct snd_card_saa7134 { | |||
83 | */ | 89 | */ |
84 | 90 | ||
85 | typedef struct snd_card_saa7134_pcm { | 91 | typedef struct snd_card_saa7134_pcm { |
86 | struct saa7134_dev *saadev; | 92 | struct saa7134_dev *dev; |
87 | 93 | ||
88 | spinlock_t lock; | 94 | spinlock_t lock; |
89 | unsigned int pcm_size; /* buffer size */ | 95 | |
90 | unsigned int pcm_count; /* bytes per period */ | ||
91 | unsigned int pcm_bps; /* bytes per second */ | ||
92 | snd_pcm_substream_t *substream; | 96 | snd_pcm_substream_t *substream; |
93 | } snd_card_saa7134_pcm_t; | 97 | } snd_card_saa7134_pcm_t; |
94 | 98 | ||
@@ -100,13 +104,11 @@ static snd_card_t *snd_saa7134_cards[SNDRV_CARDS]; | |||
100 | * | 104 | * |
101 | * Called when the capture device is released or the buffer overflows | 105 | * Called when the capture device is released or the buffer overflows |
102 | * | 106 | * |
103 | * - Copied verbatim from saa7134-oss's dsp_dma_stop. Can be dropped | 107 | * - Copied verbatim from saa7134-oss's dsp_dma_stop. |
104 | * if we just share dsp_dma_stop and use it here | ||
105 | * | 108 | * |
106 | */ | 109 | */ |
107 | 110 | ||
108 | static void saa7134_dma_stop(struct saa7134_dev *dev) | 111 | static void saa7134_dma_stop(struct saa7134_dev *dev) |
109 | |||
110 | { | 112 | { |
111 | dev->dmasound.dma_blk = -1; | 113 | dev->dmasound.dma_blk = -1; |
112 | dev->dmasound.dma_running = 0; | 114 | dev->dmasound.dma_running = 0; |
@@ -118,8 +120,7 @@ static void saa7134_dma_stop(struct saa7134_dev *dev) | |||
118 | * | 120 | * |
119 | * Called when preparing the capture device for use | 121 | * Called when preparing the capture device for use |
120 | * | 122 | * |
121 | * - Copied verbatim from saa7134-oss's dsp_dma_start. Can be dropped | 123 | * - Copied verbatim from saa7134-oss's dsp_dma_start. |
122 | * if we just share dsp_dma_start and use it here | ||
123 | * | 124 | * |
124 | */ | 125 | */ |
125 | 126 | ||
@@ -141,7 +142,8 @@ static void saa7134_dma_start(struct saa7134_dev *dev) | |||
141 | * | 142 | * |
142 | */ | 143 | */ |
143 | 144 | ||
144 | void saa7134_irq_alsa_done(struct saa7134_dev *dev, unsigned long status) | 145 | static void saa7134_irq_alsa_done(struct saa7134_dev *dev, |
146 | unsigned long status) | ||
145 | { | 147 | { |
146 | int next_blk, reg = 0; | 148 | int next_blk, reg = 0; |
147 | 149 | ||
@@ -170,9 +172,9 @@ void saa7134_irq_alsa_done(struct saa7134_dev *dev, unsigned long status) | |||
170 | if (dev->dmasound.read_count >= dev->dmasound.blksize * (dev->dmasound.blocks-2)) { | 172 | if (dev->dmasound.read_count >= dev->dmasound.blksize * (dev->dmasound.blocks-2)) { |
171 | dprintk("irq: overrun [full=%d/%d] - Blocks in %d\n",dev->dmasound.read_count, | 173 | dprintk("irq: overrun [full=%d/%d] - Blocks in %d\n",dev->dmasound.read_count, |
172 | dev->dmasound.bufsize, dev->dmasound.blocks); | 174 | dev->dmasound.bufsize, dev->dmasound.blocks); |
175 | spin_unlock(&dev->slock); | ||
173 | snd_pcm_stop(dev->dmasound.substream,SNDRV_PCM_STATE_XRUN); | 176 | snd_pcm_stop(dev->dmasound.substream,SNDRV_PCM_STATE_XRUN); |
174 | saa7134_dma_stop(dev); | 177 | return; |
175 | goto done; | ||
176 | } | 178 | } |
177 | 179 | ||
178 | /* next block addr */ | 180 | /* next block addr */ |
@@ -194,6 +196,7 @@ void saa7134_irq_alsa_done(struct saa7134_dev *dev, unsigned long status) | |||
194 | snd_pcm_period_elapsed(dev->dmasound.substream); | 196 | snd_pcm_period_elapsed(dev->dmasound.substream); |
195 | spin_lock(&dev->slock); | 197 | spin_lock(&dev->slock); |
196 | } | 198 | } |
199 | |||
197 | done: | 200 | done: |
198 | spin_unlock(&dev->slock); | 201 | spin_unlock(&dev->slock); |
199 | 202 | ||
@@ -209,7 +212,9 @@ void saa7134_irq_alsa_done(struct saa7134_dev *dev, unsigned long status) | |||
209 | 212 | ||
210 | static irqreturn_t saa7134_alsa_irq(int irq, void *dev_id, struct pt_regs *regs) | 213 | static irqreturn_t saa7134_alsa_irq(int irq, void *dev_id, struct pt_regs *regs) |
211 | { | 214 | { |
212 | struct saa7134_dev *dev = (struct saa7134_dev*) dev_id; | 215 | struct saa7134_dmasound *dmasound = dev_id; |
216 | struct saa7134_dev *dev = dmasound->priv_data; | ||
217 | |||
213 | unsigned long report, status; | 218 | unsigned long report, status; |
214 | int loop, handled = 0; | 219 | int loop, handled = 0; |
215 | 220 | ||
@@ -248,56 +253,23 @@ static int snd_card_saa7134_capture_trigger(snd_pcm_substream_t * substream, | |||
248 | int cmd) | 253 | int cmd) |
249 | { | 254 | { |
250 | snd_pcm_runtime_t *runtime = substream->runtime; | 255 | snd_pcm_runtime_t *runtime = substream->runtime; |
251 | snd_card_saa7134_pcm_t *saapcm = runtime->private_data; | 256 | snd_card_saa7134_pcm_t *pcm = runtime->private_data; |
252 | struct saa7134_dev *dev=saapcm->saadev; | 257 | struct saa7134_dev *dev=pcm->dev; |
253 | int err = 0; | 258 | int err = 0; |
254 | 259 | ||
255 | spin_lock_irq(&dev->slock); | 260 | spin_lock(&dev->slock); |
256 | if (cmd == SNDRV_PCM_TRIGGER_START) { | 261 | if (cmd == SNDRV_PCM_TRIGGER_START) { |
257 | /* start dma */ | 262 | /* start dma */ |
258 | saa7134_dma_start(dev); | 263 | saa7134_dma_start(dev); |
259 | } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { | 264 | } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { |
260 | /* stop dma */ | 265 | /* stop dma */ |
261 | saa7134_dma_stop(dev); | 266 | saa7134_dma_stop(dev); |
262 | } else { | 267 | } else { |
263 | err = -EINVAL; | 268 | err = -EINVAL; |
264 | } | 269 | } |
265 | spin_unlock_irq(&dev->slock); | 270 | spin_unlock(&dev->slock); |
266 | |||
267 | return err; | ||
268 | } | ||
269 | |||
270 | /* | ||
271 | * DMA buffer config | ||
272 | * | ||
273 | * Sets the values that will later be used as the size of the buffer, | ||
274 | * size of the fragments, and total number of fragments. | ||
275 | * Must be called during the preparation stage, before memory is | ||
276 | * allocated | ||
277 | * | ||
278 | * - Copied verbatim from saa7134-oss. Can be dropped | ||
279 | * if we just share dsp_buffer_conf from OSS. | ||
280 | */ | ||
281 | 271 | ||
282 | static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks) | 272 | return err; |
283 | { | ||
284 | if (blksize < 0x100) | ||
285 | blksize = 0x100; | ||
286 | if (blksize > 0x10000) | ||
287 | blksize = 0x10000; | ||
288 | |||
289 | if (blocks < 2) | ||
290 | blocks = 2; | ||
291 | if ((blksize * blocks) > 1024*1024) | ||
292 | blocks = 1024*1024 / blksize; | ||
293 | |||
294 | dev->dmasound.blocks = blocks; | ||
295 | dev->dmasound.blksize = blksize; | ||
296 | dev->dmasound.bufsize = blksize * blocks; | ||
297 | |||
298 | dprintk("buffer config: %d blocks / %d bytes, %d kB total\n", | ||
299 | blocks,blksize,blksize * blocks / 1024); | ||
300 | return 0; | ||
301 | } | 273 | } |
302 | 274 | ||
303 | /* | 275 | /* |
@@ -307,16 +279,16 @@ static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks) | |||
307 | * ALSA, but I was unable to use ALSA's own DMA, and had to force the | 279 | * ALSA, but I was unable to use ALSA's own DMA, and had to force the |
308 | * usage of V4L's | 280 | * usage of V4L's |
309 | * | 281 | * |
310 | * - Copied verbatim from saa7134-oss. Can be dropped | 282 | * - Copied verbatim from saa7134-oss. |
311 | * if we just share dsp_buffer_init from OSS. | 283 | * |
312 | */ | 284 | */ |
313 | 285 | ||
314 | static int dsp_buffer_init(struct saa7134_dev *dev) | 286 | static int dsp_buffer_init(struct saa7134_dev *dev) |
315 | { | 287 | { |
316 | int err; | 288 | int err; |
317 | 289 | ||
318 | if (!dev->dmasound.bufsize) | 290 | BUG_ON(!dev->dmasound.bufsize); |
319 | BUG(); | 291 | |
320 | videobuf_dma_init(&dev->dmasound.dma); | 292 | videobuf_dma_init(&dev->dmasound.dma); |
321 | err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE, | 293 | err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE, |
322 | (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT); | 294 | (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT); |
@@ -326,6 +298,28 @@ static int dsp_buffer_init(struct saa7134_dev *dev) | |||
326 | } | 298 | } |
327 | 299 | ||
328 | /* | 300 | /* |
301 | * DMA buffer release | ||
302 | * | ||
303 | * Called after closing the device, during snd_card_saa7134_capture_close | ||
304 | * | ||
305 | */ | ||
306 | |||
307 | static int dsp_buffer_free(struct saa7134_dev *dev) | ||
308 | { | ||
309 | if (!dev->dmasound.blksize) | ||
310 | BUG(); | ||
311 | |||
312 | videobuf_dma_free(&dev->dmasound.dma); | ||
313 | |||
314 | dev->dmasound.blocks = 0; | ||
315 | dev->dmasound.blksize = 0; | ||
316 | dev->dmasound.bufsize = 0; | ||
317 | |||
318 | return 0; | ||
319 | } | ||
320 | |||
321 | |||
322 | /* | ||
329 | * ALSA PCM preparation | 323 | * ALSA PCM preparation |
330 | * | 324 | * |
331 | * - One of the ALSA capture callbacks. | 325 | * - One of the ALSA capture callbacks. |
@@ -340,84 +334,30 @@ static int dsp_buffer_init(struct saa7134_dev *dev) | |||
340 | static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream) | 334 | static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream) |
341 | { | 335 | { |
342 | snd_pcm_runtime_t *runtime = substream->runtime; | 336 | snd_pcm_runtime_t *runtime = substream->runtime; |
343 | int err, bswap, sign; | 337 | int bswap, sign; |
344 | u32 fmt, control; | 338 | u32 fmt, control; |
345 | snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream); | 339 | snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream); |
346 | struct saa7134_dev *dev; | 340 | struct saa7134_dev *dev; |
347 | snd_card_saa7134_pcm_t *saapcm = runtime->private_data; | 341 | snd_card_saa7134_pcm_t *pcm = runtime->private_data; |
348 | unsigned int bps; | ||
349 | unsigned long size; | ||
350 | unsigned count; | ||
351 | 342 | ||
352 | size = snd_pcm_lib_buffer_bytes(substream); | 343 | pcm->dev->dmasound.substream = substream; |
353 | count = snd_pcm_lib_period_bytes(substream); | ||
354 | |||
355 | saapcm->saadev->dmasound.substream = substream; | ||
356 | bps = runtime->rate * runtime->channels; | ||
357 | bps *= snd_pcm_format_width(runtime->format); | ||
358 | bps /= 8; | ||
359 | if (bps <= 0) | ||
360 | return -EINVAL; | ||
361 | saapcm->pcm_bps = bps; | ||
362 | saapcm->pcm_size = snd_pcm_lib_buffer_bytes(substream); | ||
363 | saapcm->pcm_count = snd_pcm_lib_period_bytes(substream); | ||
364 | |||
365 | |||
366 | dev=saa7134->saadev; | ||
367 | |||
368 | dsp_buffer_conf(dev,saapcm->pcm_count,(saapcm->pcm_size/saapcm->pcm_count)); | ||
369 | |||
370 | err = dsp_buffer_init(dev); | ||
371 | if (0 != err) | ||
372 | goto fail2; | ||
373 | |||
374 | /* prepare buffer */ | ||
375 | if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->dmasound.dma))) | ||
376 | return err; | ||
377 | if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt))) | ||
378 | goto fail1; | ||
379 | if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->dmasound.pt, | ||
380 | dev->dmasound.dma.sglist, | ||
381 | dev->dmasound.dma.sglen, | ||
382 | 0))) | ||
383 | goto fail2; | ||
384 | 344 | ||
345 | dev = saa7134->dev; | ||
385 | 346 | ||
386 | 347 | if (snd_pcm_format_width(runtime->format) == 8) | |
387 | switch (runtime->format) { | ||
388 | case SNDRV_PCM_FORMAT_U8: | ||
389 | case SNDRV_PCM_FORMAT_S8: | ||
390 | fmt = 0x00; | 348 | fmt = 0x00; |
391 | break; | 349 | else |
392 | case SNDRV_PCM_FORMAT_U16_LE: | ||
393 | case SNDRV_PCM_FORMAT_U16_BE: | ||
394 | case SNDRV_PCM_FORMAT_S16_LE: | ||
395 | case SNDRV_PCM_FORMAT_S16_BE: | ||
396 | fmt = 0x01; | 350 | fmt = 0x01; |
397 | break; | ||
398 | default: | ||
399 | err = -EINVAL; | ||
400 | return 1; | ||
401 | } | ||
402 | 351 | ||
403 | switch (runtime->format) { | 352 | if (snd_pcm_format_signed(runtime->format)) |
404 | case SNDRV_PCM_FORMAT_S8: | ||
405 | case SNDRV_PCM_FORMAT_S16_LE: | ||
406 | case SNDRV_PCM_FORMAT_S16_BE: | ||
407 | sign = 1; | 353 | sign = 1; |
408 | break; | 354 | else |
409 | default: | ||
410 | sign = 0; | 355 | sign = 0; |
411 | break; | ||
412 | } | ||
413 | 356 | ||
414 | switch (runtime->format) { | 357 | if (snd_pcm_format_big_endian(runtime->format)) |
415 | case SNDRV_PCM_FORMAT_U16_BE: | 358 | bswap = 1; |
416 | case SNDRV_PCM_FORMAT_S16_BE: | 359 | else |
417 | bswap = 1; break; | 360 | bswap = 0; |
418 | default: | ||
419 | bswap = 0; break; | ||
420 | } | ||
421 | 361 | ||
422 | switch (dev->pci->device) { | 362 | switch (dev->pci->device) { |
423 | case PCI_DEVICE_ID_PHILIPS_SAA7134: | 363 | case PCI_DEVICE_ID_PHILIPS_SAA7134: |
@@ -445,7 +385,6 @@ static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream) | |||
445 | fmt |= 0x04; | 385 | fmt |= 0x04; |
446 | saa_writel(SAA7133_NUM_SAMPLES, dev->dmasound.blksize -1); | 386 | saa_writel(SAA7133_NUM_SAMPLES, dev->dmasound.blksize -1); |
447 | saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210 | (fmt << 24)); | 387 | saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210 | (fmt << 24)); |
448 | //saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210); | ||
449 | break; | 388 | break; |
450 | } | 389 | } |
451 | 390 | ||
@@ -459,12 +398,6 @@ static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream) | |||
459 | if (bswap) | 398 | if (bswap) |
460 | control |= SAA7134_RS_CONTROL_BSWAP; | 399 | control |= SAA7134_RS_CONTROL_BSWAP; |
461 | 400 | ||
462 | /* I should be able to use runtime->dma_addr in the control | ||
463 | byte, but it doesn't work. So I allocate the DMA using the | ||
464 | V4L functions, and force ALSA to use that as the DMA area */ | ||
465 | |||
466 | runtime->dma_area = dev->dmasound.dma.vmalloc; | ||
467 | |||
468 | saa_writel(SAA7134_RS_BA1(6),0); | 401 | saa_writel(SAA7134_RS_BA1(6),0); |
469 | saa_writel(SAA7134_RS_BA2(6),dev->dmasound.blksize); | 402 | saa_writel(SAA7134_RS_BA2(6),dev->dmasound.blksize); |
470 | saa_writel(SAA7134_RS_PITCH(6),0); | 403 | saa_writel(SAA7134_RS_PITCH(6),0); |
@@ -473,12 +406,6 @@ static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream) | |||
473 | dev->dmasound.rate = runtime->rate; | 406 | dev->dmasound.rate = runtime->rate; |
474 | 407 | ||
475 | return 0; | 408 | return 0; |
476 | fail2: | ||
477 | saa7134_pgtable_free(dev->pci,&dev->dmasound.pt); | ||
478 | fail1: | ||
479 | videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma); | ||
480 | return err; | ||
481 | |||
482 | 409 | ||
483 | } | 410 | } |
484 | 411 | ||
@@ -496,10 +423,8 @@ static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream) | |||
496 | static snd_pcm_uframes_t snd_card_saa7134_capture_pointer(snd_pcm_substream_t * substream) | 423 | static snd_pcm_uframes_t snd_card_saa7134_capture_pointer(snd_pcm_substream_t * substream) |
497 | { | 424 | { |
498 | snd_pcm_runtime_t *runtime = substream->runtime; | 425 | snd_pcm_runtime_t *runtime = substream->runtime; |
499 | snd_card_saa7134_pcm_t *saapcm = runtime->private_data; | 426 | snd_card_saa7134_pcm_t *pcm = runtime->private_data; |
500 | struct saa7134_dev *dev=saapcm->saadev; | 427 | struct saa7134_dev *dev=pcm->dev; |
501 | |||
502 | |||
503 | 428 | ||
504 | if (dev->dmasound.read_count) { | 429 | if (dev->dmasound.read_count) { |
505 | dev->dmasound.read_count -= snd_pcm_lib_period_bytes(substream); | 430 | dev->dmasound.read_count -= snd_pcm_lib_period_bytes(substream); |
@@ -540,9 +465,9 @@ static snd_pcm_hardware_t snd_card_saa7134_capture = | |||
540 | 465 | ||
541 | static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime) | 466 | static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime) |
542 | { | 467 | { |
543 | snd_card_saa7134_pcm_t *saapcm = runtime->private_data; | 468 | snd_card_saa7134_pcm_t *pcm = runtime->private_data; |
544 | 469 | ||
545 | kfree(saapcm); | 470 | kfree(pcm); |
546 | } | 471 | } |
547 | 472 | ||
548 | 473 | ||
@@ -552,17 +477,76 @@ static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime) | |||
552 | * - One of the ALSA capture callbacks. | 477 | * - One of the ALSA capture callbacks. |
553 | * | 478 | * |
554 | * Called on initialization, right before the PCM preparation | 479 | * Called on initialization, right before the PCM preparation |
555 | * Usually used in ALSA to allocate the DMA, but since we don't use the | ||
556 | * ALSA DMA it does nothing | ||
557 | * | 480 | * |
558 | */ | 481 | */ |
559 | 482 | ||
560 | static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream, | 483 | static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream, |
561 | snd_pcm_hw_params_t * hw_params) | 484 | snd_pcm_hw_params_t * hw_params) |
562 | { | 485 | { |
486 | snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream); | ||
487 | struct saa7134_dev *dev; | ||
488 | unsigned int period_size, periods; | ||
489 | int err; | ||
563 | 490 | ||
564 | return 0; | 491 | period_size = params_period_bytes(hw_params); |
492 | periods = params_periods(hw_params); | ||
493 | |||
494 | snd_assert(period_size >= 0x100 && period_size <= 0x10000, | ||
495 | return -EINVAL); | ||
496 | snd_assert(periods >= 2, return -EINVAL); | ||
497 | snd_assert(period_size * periods <= 1024 * 1024, return -EINVAL); | ||
498 | |||
499 | dev = saa7134->dev; | ||
500 | |||
501 | if (dev->dmasound.blocks == periods && | ||
502 | dev->dmasound.blksize == period_size) | ||
503 | return 0; | ||
565 | 504 | ||
505 | /* release the old buffer */ | ||
506 | if (substream->runtime->dma_area) { | ||
507 | saa7134_pgtable_free(dev->pci, &dev->dmasound.pt); | ||
508 | videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma); | ||
509 | dsp_buffer_free(dev); | ||
510 | substream->runtime->dma_area = NULL; | ||
511 | } | ||
512 | dev->dmasound.blocks = periods; | ||
513 | dev->dmasound.blksize = period_size; | ||
514 | dev->dmasound.bufsize = period_size * periods; | ||
515 | |||
516 | err = dsp_buffer_init(dev); | ||
517 | if (0 != err) { | ||
518 | dev->dmasound.blocks = 0; | ||
519 | dev->dmasound.blksize = 0; | ||
520 | dev->dmasound.bufsize = 0; | ||
521 | return err; | ||
522 | } | ||
523 | |||
524 | if (0 != (err = videobuf_dma_pci_map(dev->pci, &dev->dmasound.dma))) { | ||
525 | dsp_buffer_free(dev); | ||
526 | return err; | ||
527 | } | ||
528 | if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt))) { | ||
529 | videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma); | ||
530 | dsp_buffer_free(dev); | ||
531 | return err; | ||
532 | } | ||
533 | if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->dmasound.pt, | ||
534 | dev->dmasound.dma.sglist, | ||
535 | dev->dmasound.dma.sglen, | ||
536 | 0))) { | ||
537 | saa7134_pgtable_free(dev->pci, &dev->dmasound.pt); | ||
538 | videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma); | ||
539 | dsp_buffer_free(dev); | ||
540 | return err; | ||
541 | } | ||
542 | |||
543 | /* I should be able to use runtime->dma_addr in the control | ||
544 | byte, but it doesn't work. So I allocate the DMA using the | ||
545 | V4L functions, and force ALSA to use that as the DMA area */ | ||
546 | |||
547 | substream->runtime->dma_area = dev->dmasound.dma.vmalloc; | ||
548 | |||
549 | return 1; | ||
566 | 550 | ||
567 | } | 551 | } |
568 | 552 | ||
@@ -572,33 +556,23 @@ static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream, | |||
572 | * - One of the ALSA capture callbacks. | 556 | * - One of the ALSA capture callbacks. |
573 | * | 557 | * |
574 | * Called after closing the device, but before snd_card_saa7134_capture_close | 558 | * Called after closing the device, but before snd_card_saa7134_capture_close |
575 | * Usually used in ALSA to free the DMA, but since we don't use the | 559 | * It stops the DMA audio and releases the buffers. |
576 | * ALSA DMA I'm almost sure this isn't necessary. | ||
577 | * | 560 | * |
578 | */ | 561 | */ |
579 | 562 | ||
580 | static int snd_card_saa7134_hw_free(snd_pcm_substream_t * substream) | 563 | static int snd_card_saa7134_hw_free(snd_pcm_substream_t * substream) |
581 | { | 564 | { |
582 | return 0; | 565 | snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream); |
583 | } | 566 | struct saa7134_dev *dev; |
584 | |||
585 | /* | ||
586 | * DMA buffer release | ||
587 | * | ||
588 | * Called after closing the device, during snd_card_saa7134_capture_close | ||
589 | * | ||
590 | */ | ||
591 | 567 | ||
592 | static int dsp_buffer_free(struct saa7134_dev *dev) | 568 | dev = saa7134->dev; |
593 | { | ||
594 | if (!dev->dmasound.blksize) | ||
595 | BUG(); | ||
596 | 569 | ||
597 | videobuf_dma_free(&dev->dmasound.dma); | 570 | if (substream->runtime->dma_area) { |
598 | 571 | saa7134_pgtable_free(dev->pci, &dev->dmasound.pt); | |
599 | dev->dmasound.blocks = 0; | 572 | videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma); |
600 | dev->dmasound.blksize = 0; | 573 | dsp_buffer_free(dev); |
601 | dev->dmasound.bufsize = 0; | 574 | substream->runtime->dma_area = NULL; |
575 | } | ||
602 | 576 | ||
603 | return 0; | 577 | return 0; |
604 | } | 578 | } |
@@ -608,21 +582,12 @@ static int dsp_buffer_free(struct saa7134_dev *dev) | |||
608 | * | 582 | * |
609 | * - One of the ALSA capture callbacks. | 583 | * - One of the ALSA capture callbacks. |
610 | * | 584 | * |
611 | * Called after closing the device. It stops the DMA audio and releases | 585 | * Called after closing the device. |
612 | * the buffers | ||
613 | * | 586 | * |
614 | */ | 587 | */ |
615 | 588 | ||
616 | static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream) | 589 | static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream) |
617 | { | 590 | { |
618 | snd_card_saa7134_t *chip = snd_pcm_substream_chip(substream); | ||
619 | struct saa7134_dev *dev = chip->saadev; | ||
620 | |||
621 | /* unlock buffer */ | ||
622 | saa7134_pgtable_free(dev->pci,&dev->dmasound.pt); | ||
623 | videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma); | ||
624 | |||
625 | dsp_buffer_free(dev); | ||
626 | return 0; | 591 | return 0; |
627 | } | 592 | } |
628 | 593 | ||
@@ -639,29 +604,28 @@ static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream) | |||
639 | static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream) | 604 | static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream) |
640 | { | 605 | { |
641 | snd_pcm_runtime_t *runtime = substream->runtime; | 606 | snd_pcm_runtime_t *runtime = substream->runtime; |
642 | snd_card_saa7134_pcm_t *saapcm; | 607 | snd_card_saa7134_pcm_t *pcm; |
643 | snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream); | 608 | snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream); |
644 | struct saa7134_dev *dev = saa7134->saadev; | 609 | struct saa7134_dev *dev = saa7134->dev; |
645 | int err; | 610 | int err; |
646 | 611 | ||
647 | down(&dev->dmasound.lock); | 612 | down(&dev->dmasound.lock); |
648 | 613 | ||
649 | dev->dmasound.afmt = SNDRV_PCM_FORMAT_U8; | ||
650 | dev->dmasound.channels = 2; | ||
651 | dev->dmasound.read_count = 0; | 614 | dev->dmasound.read_count = 0; |
652 | dev->dmasound.read_offset = 0; | 615 | dev->dmasound.read_offset = 0; |
653 | 616 | ||
654 | up(&dev->dmasound.lock); | 617 | up(&dev->dmasound.lock); |
655 | 618 | ||
656 | saapcm = kzalloc(sizeof(*saapcm), GFP_KERNEL); | 619 | pcm = kzalloc(sizeof(*pcm), GFP_KERNEL); |
657 | if (saapcm == NULL) | 620 | if (pcm == NULL) |
658 | return -ENOMEM; | 621 | return -ENOMEM; |
659 | saapcm->saadev=saa7134->saadev; | ||
660 | 622 | ||
661 | spin_lock_init(&saapcm->lock); | 623 | pcm->dev=saa7134->dev; |
624 | |||
625 | spin_lock_init(&pcm->lock); | ||
662 | 626 | ||
663 | saapcm->substream = substream; | 627 | pcm->substream = substream; |
664 | runtime->private_data = saapcm; | 628 | runtime->private_data = pcm; |
665 | runtime->private_free = snd_card_saa7134_runtime_free; | 629 | runtime->private_free = snd_card_saa7134_runtime_free; |
666 | runtime->hw = snd_card_saa7134_capture; | 630 | runtime->hw = snd_card_saa7134_capture; |
667 | 631 | ||
@@ -736,7 +700,6 @@ static int snd_saa7134_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_ | |||
736 | static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) | 700 | static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) |
737 | { | 701 | { |
738 | snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol); | 702 | snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol); |
739 | unsigned long flags; | ||
740 | int change, addr = kcontrol->private_value; | 703 | int change, addr = kcontrol->private_value; |
741 | int left, right; | 704 | int left, right; |
742 | 705 | ||
@@ -750,12 +713,12 @@ static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_ | |||
750 | right = 0; | 713 | right = 0; |
751 | if (right > 20) | 714 | if (right > 20) |
752 | right = 20; | 715 | right = 20; |
753 | spin_lock_irqsave(&chip->mixer_lock, flags); | 716 | spin_lock_irq(&chip->mixer_lock); |
754 | change = chip->mixer_volume[addr][0] != left || | 717 | change = chip->mixer_volume[addr][0] != left || |
755 | chip->mixer_volume[addr][1] != right; | 718 | chip->mixer_volume[addr][1] != right; |
756 | chip->mixer_volume[addr][0] = left; | 719 | chip->mixer_volume[addr][0] = left; |
757 | chip->mixer_volume[addr][1] = right; | 720 | chip->mixer_volume[addr][1] = right; |
758 | spin_unlock_irqrestore(&chip->mixer_lock, flags); | 721 | spin_unlock_irq(&chip->mixer_lock); |
759 | return change; | 722 | return change; |
760 | } | 723 | } |
761 | 724 | ||
@@ -777,38 +740,37 @@ static int snd_saa7134_capsrc_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_ | |||
777 | static int snd_saa7134_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) | 740 | static int snd_saa7134_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) |
778 | { | 741 | { |
779 | snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol); | 742 | snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol); |
780 | unsigned long flags; | ||
781 | int addr = kcontrol->private_value; | 743 | int addr = kcontrol->private_value; |
782 | 744 | ||
783 | spin_lock_irqsave(&chip->mixer_lock, flags); | 745 | spin_lock_irq(&chip->mixer_lock); |
784 | ucontrol->value.integer.value[0] = chip->capture_source[addr][0]; | 746 | ucontrol->value.integer.value[0] = chip->capture_source[addr][0]; |
785 | ucontrol->value.integer.value[1] = chip->capture_source[addr][1]; | 747 | ucontrol->value.integer.value[1] = chip->capture_source[addr][1]; |
786 | spin_unlock_irqrestore(&chip->mixer_lock, flags); | 748 | spin_unlock_irq(&chip->mixer_lock); |
749 | |||
787 | return 0; | 750 | return 0; |
788 | } | 751 | } |
789 | 752 | ||
790 | static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) | 753 | static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) |
791 | { | 754 | { |
792 | snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol); | 755 | snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol); |
793 | unsigned long flags; | ||
794 | int change, addr = kcontrol->private_value; | 756 | int change, addr = kcontrol->private_value; |
795 | int left, right; | 757 | int left, right; |
796 | u32 anabar, xbarin; | 758 | u32 anabar, xbarin; |
797 | int analog_io, rate; | 759 | int analog_io, rate; |
798 | struct saa7134_dev *dev; | 760 | struct saa7134_dev *dev; |
799 | 761 | ||
800 | dev = chip->saadev; | 762 | dev = chip->dev; |
801 | 763 | ||
802 | left = ucontrol->value.integer.value[0] & 1; | 764 | left = ucontrol->value.integer.value[0] & 1; |
803 | right = ucontrol->value.integer.value[1] & 1; | 765 | right = ucontrol->value.integer.value[1] & 1; |
804 | spin_lock_irqsave(&chip->mixer_lock, flags); | 766 | spin_lock_irq(&chip->mixer_lock); |
805 | 767 | ||
806 | change = chip->capture_source[addr][0] != left || | 768 | change = chip->capture_source[addr][0] != left || |
807 | chip->capture_source[addr][1] != right; | 769 | chip->capture_source[addr][1] != right; |
808 | chip->capture_source[addr][0] = left; | 770 | chip->capture_source[addr][0] = left; |
809 | chip->capture_source[addr][1] = right; | 771 | chip->capture_source[addr][1] = right; |
810 | dev->dmasound.input=addr; | 772 | dev->dmasound.input=addr; |
811 | spin_unlock_irqrestore(&chip->mixer_lock, flags); | 773 | spin_unlock_irq(&chip->mixer_lock); |
812 | 774 | ||
813 | 775 | ||
814 | if (change) { | 776 | if (change) { |
@@ -898,43 +860,44 @@ static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip) | |||
898 | return 0; | 860 | return 0; |
899 | } | 861 | } |
900 | 862 | ||
901 | static int snd_saa7134_free(snd_card_saa7134_t *chip) | 863 | static void snd_saa7134_free(snd_card_t * card) |
902 | { | 864 | { |
903 | return 0; | 865 | snd_card_saa7134_t *chip = card->private_data; |
904 | } | 866 | |
867 | if (chip->dev->dmasound.priv_data == NULL) | ||
868 | return; | ||
869 | |||
870 | if (chip->irq >= 0) { | ||
871 | synchronize_irq(chip->irq); | ||
872 | free_irq(chip->irq, &chip->dev->dmasound); | ||
873 | } | ||
874 | |||
875 | chip->dev->dmasound.priv_data = NULL; | ||
905 | 876 | ||
906 | static int snd_saa7134_dev_free(snd_device_t *device) | ||
907 | { | ||
908 | snd_card_saa7134_t *chip = device->device_data; | ||
909 | return snd_saa7134_free(chip); | ||
910 | } | 877 | } |
911 | 878 | ||
912 | /* | 879 | /* |
913 | * ALSA initialization | 880 | * ALSA initialization |
914 | * | 881 | * |
915 | * Called by saa7134-core, it creates the basic structures and registers | 882 | * Called by the init routine, once for each saa7134 device present, |
916 | * the ALSA devices | 883 | * it creates the basic structures and registers the ALSA devices |
917 | * | 884 | * |
918 | */ | 885 | */ |
919 | 886 | ||
920 | int alsa_card_saa7134_create (struct saa7134_dev *saadev) | 887 | static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum) |
921 | { | 888 | { |
922 | static int dev; | ||
923 | 889 | ||
924 | snd_card_t *card; | 890 | snd_card_t *card; |
925 | snd_card_saa7134_t *chip; | 891 | snd_card_saa7134_t *chip; |
926 | int err; | 892 | int err; |
927 | static snd_device_ops_t ops = { | ||
928 | .dev_free = snd_saa7134_dev_free, | ||
929 | }; | ||
930 | 893 | ||
931 | 894 | ||
932 | if (dev >= SNDRV_CARDS) | 895 | if (devnum >= SNDRV_CARDS) |
933 | return -ENODEV; | 896 | return -ENODEV; |
934 | if (!enable[dev]) | 897 | if (!enable[devnum]) |
935 | return -ENODEV; | 898 | return -ENODEV; |
936 | 899 | ||
937 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 900 | card = snd_card_new(index[devnum], id[devnum], THIS_MODULE, sizeof(snd_card_saa7134_t)); |
938 | 901 | ||
939 | if (card == NULL) | 902 | if (card == NULL) |
940 | return -ENOMEM; | 903 | return -ENOMEM; |
@@ -943,34 +906,33 @@ int alsa_card_saa7134_create (struct saa7134_dev *saadev) | |||
943 | 906 | ||
944 | /* Card "creation" */ | 907 | /* Card "creation" */ |
945 | 908 | ||
946 | chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); | 909 | card->private_free = snd_saa7134_free; |
947 | if (chip == NULL) { | 910 | chip = (snd_card_saa7134_t *) card->private_data; |
948 | return -ENOMEM; | ||
949 | } | ||
950 | 911 | ||
951 | spin_lock_init(&chip->lock); | 912 | spin_lock_init(&chip->lock); |
952 | spin_lock_init(&chip->mixer_lock); | 913 | spin_lock_init(&chip->mixer_lock); |
953 | 914 | ||
954 | chip->saadev = saadev; | 915 | chip->dev = dev; |
955 | 916 | ||
956 | chip->card = card; | 917 | chip->card = card; |
957 | 918 | ||
958 | chip->pci = saadev->pci; | 919 | chip->pci = dev->pci; |
959 | chip->irq = saadev->pci->irq; | 920 | chip->iobase = pci_resource_start(dev->pci, 0); |
960 | chip->iobase = pci_resource_start(saadev->pci, 0); | ||
961 | 921 | ||
962 | err = request_irq(saadev->pci->irq, saa7134_alsa_irq, | 922 | |
963 | SA_SHIRQ | SA_INTERRUPT, saadev->name, saadev); | 923 | err = request_irq(dev->pci->irq, saa7134_alsa_irq, |
924 | SA_SHIRQ | SA_INTERRUPT, dev->name, | ||
925 | (void*) &dev->dmasound); | ||
964 | 926 | ||
965 | if (err < 0) { | 927 | if (err < 0) { |
966 | printk(KERN_ERR "%s: can't get IRQ %d for ALSA\n", | 928 | printk(KERN_ERR "%s: can't get IRQ %d for ALSA\n", |
967 | saadev->name, saadev->pci->irq); | 929 | dev->name, dev->pci->irq); |
968 | goto __nodev; | 930 | goto __nodev; |
969 | } | 931 | } |
970 | 932 | ||
971 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { | 933 | chip->irq = dev->pci->irq; |
972 | goto __nodev; | 934 | |
973 | } | 935 | init_MUTEX(&dev->dmasound.lock); |
974 | 936 | ||
975 | if ((err = snd_card_saa7134_new_mixer(chip)) < 0) | 937 | if ((err = snd_card_saa7134_new_mixer(chip)) < 0) |
976 | goto __nodev; | 938 | goto __nodev; |
@@ -984,19 +946,36 @@ int alsa_card_saa7134_create (struct saa7134_dev *saadev) | |||
984 | 946 | ||
985 | strcpy(card->shortname, "SAA7134"); | 947 | strcpy(card->shortname, "SAA7134"); |
986 | sprintf(card->longname, "%s at 0x%lx irq %d", | 948 | sprintf(card->longname, "%s at 0x%lx irq %d", |
987 | chip->saadev->name, chip->iobase, chip->irq); | 949 | chip->dev->name, chip->iobase, chip->irq); |
950 | |||
951 | printk(KERN_INFO "%s/alsa: %s registered as card %d\n",dev->name,card->longname,index[devnum]); | ||
988 | 952 | ||
989 | if ((err = snd_card_register(card)) == 0) { | 953 | if ((err = snd_card_register(card)) == 0) { |
990 | snd_saa7134_cards[dev] = card; | 954 | snd_saa7134_cards[devnum] = card; |
991 | return 0; | 955 | return 0; |
992 | } | 956 | } |
993 | 957 | ||
994 | __nodev: | 958 | __nodev: |
995 | snd_card_free(card); | 959 | snd_card_free(card); |
996 | kfree(chip); | ||
997 | return err; | 960 | return err; |
998 | } | 961 | } |
999 | 962 | ||
963 | |||
964 | static int alsa_device_init(struct saa7134_dev *dev) | ||
965 | { | ||
966 | dev->dmasound.priv_data = dev; | ||
967 | alsa_card_saa7134_create(dev,dev->nr); | ||
968 | return 1; | ||
969 | } | ||
970 | |||
971 | static int alsa_device_exit(struct saa7134_dev *dev) | ||
972 | { | ||
973 | |||
974 | snd_card_free(snd_saa7134_cards[dev->nr]); | ||
975 | snd_saa7134_cards[dev->nr] = NULL; | ||
976 | return 1; | ||
977 | } | ||
978 | |||
1000 | /* | 979 | /* |
1001 | * Module initializer | 980 | * Module initializer |
1002 | * | 981 | * |
@@ -1007,17 +986,30 @@ __nodev: | |||
1007 | 986 | ||
1008 | static int saa7134_alsa_init(void) | 987 | static int saa7134_alsa_init(void) |
1009 | { | 988 | { |
1010 | struct saa7134_dev *saadev = NULL; | 989 | struct saa7134_dev *dev = NULL; |
1011 | struct list_head *list; | 990 | struct list_head *list; |
991 | |||
992 | if (!dmasound_init && !dmasound_exit) { | ||
993 | dmasound_init = alsa_device_init; | ||
994 | dmasound_exit = alsa_device_exit; | ||
995 | } else { | ||
996 | printk(KERN_WARNING "saa7134 ALSA: can't load, DMA sound handler already assigned (probably to OSS)\n"); | ||
997 | return -EBUSY; | ||
998 | } | ||
1012 | 999 | ||
1013 | printk(KERN_INFO "saa7134 ALSA driver for DMA sound loaded\n"); | 1000 | printk(KERN_INFO "saa7134 ALSA driver for DMA sound loaded\n"); |
1014 | 1001 | ||
1015 | list_for_each(list,&saa7134_devlist) { | 1002 | list_for_each(list,&saa7134_devlist) { |
1016 | saadev = list_entry(list, struct saa7134_dev, devlist); | 1003 | dev = list_entry(list, struct saa7134_dev, devlist); |
1017 | alsa_card_saa7134_create(saadev); | 1004 | if (dev->dmasound.priv_data == NULL) { |
1018 | } | 1005 | alsa_device_init(dev); |
1006 | } else { | ||
1007 | printk(KERN_ERR "saa7134 ALSA: DMA sound is being handled by OSS. ignoring %s\n",dev->name); | ||
1008 | return -EBUSY; | ||
1009 | } | ||
1010 | } | ||
1019 | 1011 | ||
1020 | if (saadev == NULL) | 1012 | if (dev == NULL) |
1021 | printk(KERN_INFO "saa7134 ALSA: no saa7134 cards found\n"); | 1013 | printk(KERN_INFO "saa7134 ALSA: no saa7134 cards found\n"); |
1022 | 1014 | ||
1023 | return 0; | 1015 | return 0; |
@@ -1028,7 +1020,7 @@ static int saa7134_alsa_init(void) | |||
1028 | * Module destructor | 1020 | * Module destructor |
1029 | */ | 1021 | */ |
1030 | 1022 | ||
1031 | void saa7134_alsa_exit(void) | 1023 | static void saa7134_alsa_exit(void) |
1032 | { | 1024 | { |
1033 | int idx; | 1025 | int idx; |
1034 | 1026 | ||
@@ -1036,12 +1028,18 @@ void saa7134_alsa_exit(void) | |||
1036 | snd_card_free(snd_saa7134_cards[idx]); | 1028 | snd_card_free(snd_saa7134_cards[idx]); |
1037 | } | 1029 | } |
1038 | 1030 | ||
1031 | dmasound_init = NULL; | ||
1032 | dmasound_exit = NULL; | ||
1039 | printk(KERN_INFO "saa7134 ALSA driver for DMA sound unloaded\n"); | 1033 | printk(KERN_INFO "saa7134 ALSA driver for DMA sound unloaded\n"); |
1040 | 1034 | ||
1041 | return; | 1035 | return; |
1042 | } | 1036 | } |
1043 | 1037 | ||
1044 | module_init(saa7134_alsa_init); | 1038 | /* We initialize this late, to make sure the sound system is up and running */ |
1039 | late_initcall(saa7134_alsa_init); | ||
1045 | module_exit(saa7134_alsa_exit); | 1040 | module_exit(saa7134_alsa_exit); |
1046 | MODULE_LICENSE("GPL"); | 1041 | MODULE_LICENSE("GPL"); |
1047 | MODULE_AUTHOR("Ricardo Cerqueira"); | 1042 | MODULE_AUTHOR("Ricardo Cerqueira"); |
1043 | |||
1044 | |||
1045 | |||