aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/saa7134/saa7134-alsa.c
diff options
context:
space:
mode:
authorRicardo Cerqueira <v4l@cerqueira.org>2005-11-09 00:37:14 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-09 10:56:16 -0500
commitb2c15ea9b23c216bb49303c076bbdcef7e7ba278 (patch)
treedf02f03b2952947b8eaba6128d176781699b10b3 /drivers/media/video/saa7134/saa7134-alsa.c
parentc06f57f55a0e499ec38fbb62812ad3fe08ad246e (diff)
[PATCH] v4l: 725: fixed kernel oops when hotswapping pc cards
- Fixed kernel oops when hotswapping PC Cards Signed-off-by: Ricardo Cerqueira <v4l@cerqueira.org> Signed-off-by: Nickolay V. Shmyrev <nshmyrev@yandex.ru> Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/media/video/saa7134/saa7134-alsa.c')
-rw-r--r--drivers/media/video/saa7134/saa7134-alsa.c270
1 files changed, 210 insertions, 60 deletions
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c
index 84eeeba21d74..cf4ee6d6ef64 100644
--- a/drivers/media/video/saa7134/saa7134-alsa.c
+++ b/drivers/media/video/saa7134/saa7134-alsa.c
@@ -4,15 +4,7 @@
4 * 4 *
5 * 5 *
6 * Caveats: 6 * Caveats:
7 * I still haven't got the mixer settings right.
8 *
9 * - Volume doesn't work (it's always at max) 7 * - Volume doesn't work (it's always at max)
10 * - There's no "memory" of the capture channel. It can be changed,
11 * but alsamixer doesn't show it after a module restart (rmmod/insmod)
12 *
13 * Hotswapping DOES NOT work yet! Please remove the module before
14 * inserting cardbus cards. pcmcia-cs or pccardd should load it
15 * properly after insertion, and things will work
16 * 8 *
17 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
@@ -49,6 +41,10 @@ static unsigned int alsa_debug = 0;
49module_param(alsa_debug, int, 0644); 41module_param(alsa_debug, int, 0644);
50MODULE_PARM_DESC(alsa_debug,"enable debug messages [alsa]"); 42MODULE_PARM_DESC(alsa_debug,"enable debug messages [alsa]");
51 43
44/*
45 * Configuration macros
46 */
47
52#define MAX_PCM_DEVICES 1 48#define MAX_PCM_DEVICES 1
53#define MAX_PCM_SUBSTREAMS 1 49#define MAX_PCM_SUBSTREAMS 1
54 50
@@ -67,20 +63,21 @@ MODULE_PARM_DESC(alsa_debug,"enable debug messages [alsa]");
67#define USE_PERIODS_MAX 1024 63#define USE_PERIODS_MAX 1024
68#endif 64#endif
69 65
70 66#define MIXER_ADDR_TVTUNER 0
71#define dprintk(fmt, arg...) if (alsa_debug) \ 67#define MIXER_ADDR_LINE1 1
72 printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ## arg) 68#define MIXER_ADDR_LINE2 2
73 69#define MIXER_ADDR_LAST 2
74 70
75static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 71static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
76static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 72static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
77static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0}; 73static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
78 74
79#define MIXER_ADDR_TVTUNER 0 75#define dprintk(fmt, arg...) if (alsa_debug) \
80#define MIXER_ADDR_LINE1 1 76 printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ## arg)
81#define MIXER_ADDR_LINE2 2
82#define MIXER_ADDR_LAST 2
83 77
78/*
79 * Main chip structure
80 */
84typedef struct snd_card_saa7134 { 81typedef struct snd_card_saa7134 {
85 snd_card_t *card; 82 snd_card_t *card;
86 spinlock_t mixer_lock; 83 spinlock_t mixer_lock;
@@ -95,6 +92,10 @@ typedef struct snd_card_saa7134 {
95 spinlock_t lock; 92 spinlock_t lock;
96} snd_card_saa7134_t; 93} snd_card_saa7134_t;
97 94
95/*
96 * PCM structure
97 */
98
98typedef struct snd_card_saa7134_pcm { 99typedef struct snd_card_saa7134_pcm {
99 struct saa7134_dev *saadev; 100 struct saa7134_dev *saadev;
100 101
@@ -107,13 +108,34 @@ typedef struct snd_card_saa7134_pcm {
107 108
108static snd_card_t *snd_saa7134_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; 109static snd_card_t *snd_saa7134_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
109 110
111/*
112 * saa7134 DMA audio stop
113 *
114 * Called when the capture device is released or the buffer overflows
115 *
116 * - Copied verbatim from saa7134-oss's dsp_dma_stop. Can be dropped
117 * if we just share dsp_dma_stop and use it here
118 *
119 */
120
110static void saa7134_dma_stop(struct saa7134_dev *dev) 121static void saa7134_dma_stop(struct saa7134_dev *dev)
122
111{ 123{
112 dev->oss.dma_blk = -1; 124 dev->oss.dma_blk = -1;
113 dev->oss.dma_running = 0; 125 dev->oss.dma_running = 0;
114 saa7134_set_dmabits(dev); 126 saa7134_set_dmabits(dev);
115} 127}
116 128
129/*
130 * saa7134 DMA audio start
131 *
132 * Called when preparing the capture device for use
133 *
134 * - Copied verbatim from saa7134-oss's dsp_dma_start. Can be dropped
135 * if we just share dsp_dma_start and use it here
136 *
137 */
138
117static void saa7134_dma_start(struct saa7134_dev *dev) 139static void saa7134_dma_start(struct saa7134_dev *dev)
118{ 140{
119 dev->oss.dma_blk = 0; 141 dev->oss.dma_blk = 0;
@@ -121,6 +143,17 @@ static void saa7134_dma_start(struct saa7134_dev *dev)
121 saa7134_set_dmabits(dev); 143 saa7134_set_dmabits(dev);
122} 144}
123 145
146/*
147 * saa7134 audio DMA IRQ handler
148 *
149 * Called whenever we get an SAA7134_IRQ_REPORT_DONE_RA3 interrupt
150 * Handles shifting between the 2 buffers, manages the read counters,
151 * and notifies ALSA when periods elapse
152 *
153 * - Mostly copied from saa7134-oss's saa7134_irq_oss_done.
154 *
155 */
156
124void saa7134_irq_alsa_done(struct saa7134_dev *dev, unsigned long status) 157void saa7134_irq_alsa_done(struct saa7134_dev *dev, unsigned long status)
125{ 158{
126 int next_blk, reg = 0; 159 int next_blk, reg = 0;
@@ -179,6 +212,15 @@ void saa7134_irq_alsa_done(struct saa7134_dev *dev, unsigned long status)
179 212
180} 213}
181 214
215/*
216 * ALSA capture trigger
217 *
218 * - One of the ALSA capture callbacks.
219 *
220 * Called whenever a capture is started or stopped. Must be defined,
221 * but there's nothing we want to do here
222 *
223 */
182 224
183static int snd_card_saa7134_capture_trigger(snd_pcm_substream_t * substream, 225static int snd_card_saa7134_capture_trigger(snd_pcm_substream_t * substream,
184 int cmd) 226 int cmd)
@@ -186,6 +228,18 @@ static int snd_card_saa7134_capture_trigger(snd_pcm_substream_t * substream,
186 return 0; 228 return 0;
187} 229}
188 230
231/*
232 * DMA buffer config
233 *
234 * Sets the values that will later be used as the size of the buffer,
235 * size of the fragments, and total number of fragments.
236 * Must be called during the preparation stage, before memory is
237 * allocated
238 *
239 * - Copied verbatim from saa7134-oss. Can be dropped
240 * if we just share dsp_buffer_conf from OSS.
241 */
242
189static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks) 243static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
190{ 244{
191 if (blksize < 0x100) 245 if (blksize < 0x100)
@@ -207,6 +261,17 @@ static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
207 return 0; 261 return 0;
208} 262}
209 263
264/*
265 * DMA buffer initialization
266 *
267 * Uses V4L functions to initialize the DMA. Shouldn't be necessary in
268 * ALSA, but I was unable to use ALSA's own DMA, and had to force the
269 * usage of V4L's
270 *
271 * - Copied verbatim from saa7134-oss. Can be dropped
272 * if we just share dsp_buffer_init from OSS.
273 */
274
210static int dsp_buffer_init(struct saa7134_dev *dev) 275static int dsp_buffer_init(struct saa7134_dev *dev)
211{ 276{
212 int err; 277 int err;
@@ -221,8 +286,19 @@ static int dsp_buffer_init(struct saa7134_dev *dev)
221 return 0; 286 return 0;
222} 287}
223 288
289/*
290 * ALSA PCM preparation
291 *
292 * - One of the ALSA capture callbacks.
293 *
294 * Called right after the capture device is opened, this function configures
295 * the buffer using the previously defined functions, allocates the memory,
296 * sets up the hardware registers, and then starts the DMA. When this function
297 * returns, the audio should be flowing.
298 *
299 */
224 300
225static int snd_card_saa7134_pcm_prepare(snd_pcm_substream_t * substream) 301static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream)
226{ 302{
227 snd_pcm_runtime_t *runtime = substream->runtime; 303 snd_pcm_runtime_t *runtime = substream->runtime;
228 int err, bswap, sign; 304 int err, bswap, sign;
@@ -329,7 +405,6 @@ static int snd_card_saa7134_pcm_prepare(snd_pcm_substream_t * substream)
329 fmt |= (2 << 4); 405 fmt |= (2 << 4);
330 if (!sign) 406 if (!sign)
331 fmt |= 0x04; 407 fmt |= 0x04;
332 //saa_writel(SAA7133_NUM_SAMPLES, dev->oss.blksize -1);
333 saa_writel(SAA7133_NUM_SAMPLES, dev->oss.blksize -1); 408 saa_writel(SAA7133_NUM_SAMPLES, dev->oss.blksize -1);
334 saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210 | (fmt << 24)); 409 saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210 | (fmt << 24));
335 //saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210); 410 //saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210);
@@ -346,7 +421,12 @@ static int snd_card_saa7134_pcm_prepare(snd_pcm_substream_t * substream)
346 if (bswap) 421 if (bswap)
347 control |= SAA7134_RS_CONTROL_BSWAP; 422 control |= SAA7134_RS_CONTROL_BSWAP;
348 423
424 /* I should be able to use runtime->dma_addr in the control
425 byte, but it doesn't work. So I allocate the DMA using the
426 V4L functions, and force ALSA to use that as the DMA area */
427
349 runtime->dma_area = dev->oss.dma.vmalloc; 428 runtime->dma_area = dev->oss.dma.vmalloc;
429
350 saa_writel(SAA7134_RS_BA1(6),0); 430 saa_writel(SAA7134_RS_BA1(6),0);
351 saa_writel(SAA7134_RS_BA2(6),dev->oss.blksize); 431 saa_writel(SAA7134_RS_BA2(6),dev->oss.blksize);
352 saa_writel(SAA7134_RS_PITCH(6),0); 432 saa_writel(SAA7134_RS_PITCH(6),0);
@@ -368,12 +448,18 @@ static int snd_card_saa7134_pcm_prepare(snd_pcm_substream_t * substream)
368 448
369} 449}
370 450
371static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream) 451/*
372{ 452 * ALSA pointer fetching
373 return snd_card_saa7134_pcm_prepare(substream); 453 *
374} 454 * - One of the ALSA capture callbacks.
455 *
456 * Called whenever a period elapses, it must return the current hardware
457 * position of the buffer.
458 * Also resets the read counter used to prevent overruns
459 *
460 */
375 461
376static snd_pcm_uframes_t snd_card_saa7134_pointer(snd_pcm_substream_t * substream) 462static snd_pcm_uframes_t snd_card_saa7134_capture_pointer(snd_pcm_substream_t * substream)
377{ 463{
378 snd_pcm_runtime_t *runtime = substream->runtime; 464 snd_pcm_runtime_t *runtime = substream->runtime;
379 snd_card_saa7134_pcm_t *saapcm = runtime->private_data; 465 snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
@@ -388,15 +474,12 @@ static snd_pcm_uframes_t snd_card_saa7134_pointer(snd_pcm_substream_t * substrea
388 dev->oss.read_offset = 0; 474 dev->oss.read_offset = 0;
389 } 475 }
390 476
391 //return bytes_to_frames(runtime, saa_readl(dev->oss.recording_on));
392 return bytes_to_frames(runtime, dev->oss.read_offset); 477 return bytes_to_frames(runtime, dev->oss.read_offset);
393} 478}
394 479
395 480/*
396static snd_pcm_uframes_t snd_card_saa7134_capture_pointer(snd_pcm_substream_t * substream) 481 * ALSA hardware capabilities definition
397{ 482 */
398 return snd_card_saa7134_pointer(substream);
399}
400 483
401static snd_pcm_hardware_t snd_card_saa7134_capture = 484static snd_pcm_hardware_t snd_card_saa7134_capture =
402{ 485{
@@ -425,6 +508,17 @@ static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime)
425} 508}
426 509
427 510
511/*
512 * ALSA hardware params
513 *
514 * - One of the ALSA capture callbacks.
515 *
516 * Called on initialization, right before the PCM preparation
517 * Usually used in ALSA to allocate the DMA, but since we don't use the
518 * ALSA DMA I'm almost sure this isn't necessary.
519 *
520 */
521
428static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream, 522static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream,
429 snd_pcm_hw_params_t * hw_params) 523 snd_pcm_hw_params_t * hw_params)
430{ 524{
@@ -434,11 +528,29 @@ static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream,
434 528
435} 529}
436 530
531/*
532 * ALSA hardware release
533 *
534 * - One of the ALSA capture callbacks.
535 *
536 * Called after closing the device, but before snd_card_saa7134_capture_close
537 * Usually used in ALSA to free the DMA, but since we don't use the
538 * ALSA DMA I'm almost sure this isn't necessary.
539 *
540 */
541
437static int snd_card_saa7134_hw_free(snd_pcm_substream_t * substream) 542static int snd_card_saa7134_hw_free(snd_pcm_substream_t * substream)
438{ 543{
439 return snd_pcm_lib_free_pages(substream); 544 return snd_pcm_lib_free_pages(substream);
440} 545}
441 546
547/*
548 * DMA buffer release
549 *
550 * Called after closing the device, during snd_card_saa7134_capture_close
551 *
552 */
553
442static int dsp_buffer_free(struct saa7134_dev *dev) 554static int dsp_buffer_free(struct saa7134_dev *dev)
443{ 555{
444 if (!dev->oss.blksize) 556 if (!dev->oss.blksize)
@@ -453,9 +565,20 @@ static int dsp_buffer_free(struct saa7134_dev *dev)
453 return 0; 565 return 0;
454} 566}
455 567
568/*
569 * ALSA capture finish
570 *
571 * - One of the ALSA capture callbacks.
572 *
573 * Called after closing the device. It stops the DMA audio and releases
574 * the buffers
575 *
576 */
456 577
457static int saa7134_cap_close(struct saa7134_dev *dev) 578static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream)
458{ 579{
580 snd_card_saa7134_t *chip = snd_pcm_substream_chip(substream);
581 struct saa7134_dev *dev = chip->saadev;
459 unsigned long flags; 582 unsigned long flags;
460 583
461 /* stop dma */ 584 /* stop dma */
@@ -471,8 +594,23 @@ static int saa7134_cap_close(struct saa7134_dev *dev)
471 return 0; 594 return 0;
472} 595}
473 596
597/*
598 * ALSA capture start
599 *
600 * - One of the ALSA capture callbacks.
601 *
602 * Called when opening the device. It creates and populates the PCM
603 * structure
604 *
605 */
474 606
475static int saa7134_cap_open(struct saa7134_dev *dev) { 607static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream)
608{
609 snd_pcm_runtime_t *runtime = substream->runtime;
610 snd_card_saa7134_pcm_t *saapcm;
611 snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
612 struct saa7134_dev *dev = saa7134->saadev;
613 int err;
476 614
477 down(&dev->oss.lock); 615 down(&dev->oss.lock);
478 616
@@ -483,18 +621,6 @@ static int saa7134_cap_open(struct saa7134_dev *dev) {
483 621
484 up(&dev->oss.lock); 622 up(&dev->oss.lock);
485 623
486 return 0;
487}
488
489static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream)
490{
491 snd_pcm_runtime_t *runtime = substream->runtime;
492 snd_card_saa7134_pcm_t *saapcm;
493 snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
494 int err;
495
496 saa7134_cap_open(saa7134->saadev);
497
498 saapcm = kcalloc(1, sizeof(*saapcm), GFP_KERNEL); 624 saapcm = kcalloc(1, sizeof(*saapcm), GFP_KERNEL);
499 if (saapcm == NULL) 625 if (saapcm == NULL)
500 return -ENOMEM; 626 return -ENOMEM;
@@ -513,13 +639,9 @@ static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream)
513 return 0; 639 return 0;
514} 640}
515 641
516static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream) 642/*
517{ 643 * ALSA capture callbacks definition
518 snd_card_saa7134_t *chip = snd_pcm_substream_chip(substream); 644 */
519
520 saa7134_cap_close(chip->saadev);
521 return 0;
522}
523 645
524static snd_pcm_ops_t snd_card_saa7134_capture_ops = { 646static snd_pcm_ops_t snd_card_saa7134_capture_ops = {
525 .open = snd_card_saa7134_capture_open, 647 .open = snd_card_saa7134_capture_open,
@@ -532,7 +654,15 @@ static snd_pcm_ops_t snd_card_saa7134_capture_ops = {
532 .pointer = snd_card_saa7134_capture_pointer, 654 .pointer = snd_card_saa7134_capture_pointer,
533}; 655};
534 656
535static int __init snd_card_saa7134_pcm(snd_card_saa7134_t *saa7134, int device) 657/*
658 * ALSA PCM setup
659 *
660 * Called when initializing the board. Sets up the name and hooks up
661 * the callbacks
662 *
663 */
664
665static int snd_card_saa7134_pcm(snd_card_saa7134_t *saa7134, int device)
536{ 666{
537 snd_pcm_t *pcm; 667 snd_pcm_t *pcm;
538 int err; 668 int err;
@@ -612,7 +742,7 @@ static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
612static int snd_saa7134_capsrc_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo) 742static int snd_saa7134_capsrc_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
613{ 743{
614 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 744 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
615 uinfo->count = 1; 745 uinfo->count = 2;
616 uinfo->value.integer.min = 0; 746 uinfo->value.integer.min = 0;
617 uinfo->value.integer.max = 1; 747 uinfo->value.integer.max = 1;
618 return 0; 748 return 0;
@@ -647,7 +777,7 @@ static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
647 right = ucontrol->value.integer.value[1] & 1; 777 right = ucontrol->value.integer.value[1] & 1;
648 spin_lock_irqsave(&chip->mixer_lock, flags); 778 spin_lock_irqsave(&chip->mixer_lock, flags);
649 779
650 change = chip->capture_source[addr][0] != left && 780 change = chip->capture_source[addr][0] != left ||
651 chip->capture_source[addr][1] != right; 781 chip->capture_source[addr][1] != right;
652 chip->capture_source[addr][0] = left; 782 chip->capture_source[addr][0] = left;
653 chip->capture_source[addr][1] = right; 783 chip->capture_source[addr][1] = right;
@@ -655,7 +785,8 @@ static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
655 spin_unlock_irqrestore(&chip->mixer_lock, flags); 785 spin_unlock_irqrestore(&chip->mixer_lock, flags);
656 786
657 787
658 switch (dev->pci->device) { 788 if (change) {
789 switch (dev->pci->device) {
659 790
660 case PCI_DEVICE_ID_PHILIPS_SAA7134: 791 case PCI_DEVICE_ID_PHILIPS_SAA7134:
661 switch (addr) { 792 switch (addr) {
@@ -702,7 +833,8 @@ static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
702 saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1, 0); 833 saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1, 0);
703 saa_writel(SAA7133_ANALOG_IO_SELECT, 0); 834 saa_writel(SAA7133_ANALOG_IO_SELECT, 0);
704 } 835 }
705 } 836 }
837 }
706 838
707 return change; 839 return change;
708} 840}
@@ -716,7 +848,15 @@ SAA713x_VOLUME("Line Volume", 2, MIXER_ADDR_LINE2),
716SAA713x_CAPSRC("Line Capture Switch", 2, MIXER_ADDR_LINE2), 848SAA713x_CAPSRC("Line Capture Switch", 2, MIXER_ADDR_LINE2),
717}; 849};
718 850
719static int __init snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip) 851/*
852 * ALSA mixer setup
853 *
854 * Called when initializing the board. Sets up the name and hooks up
855 * the callbacks
856 *
857 */
858
859static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip)
720{ 860{
721 snd_card_t *card = chip->card; 861 snd_card_t *card = chip->card;
722 unsigned int idx; 862 unsigned int idx;
@@ -743,11 +883,19 @@ static int snd_saa7134_dev_free(snd_device_t *device)
743 return snd_saa7134_free(chip); 883 return snd_saa7134_free(chip);
744} 884}
745 885
886/*
887 * ALSA initialization
888 *
889 * Called by saa7134-core, it creates the basic structures and registers
890 * the ALSA devices
891 *
892 */
893
746int alsa_card_saa7134_create(struct saa7134_dev *saadev) 894int alsa_card_saa7134_create(struct saa7134_dev *saadev)
747{ 895{
748 static int dev; 896 static int dev;
749 snd_card_t *card; 897 snd_card_t *card;
750 struct snd_card_saa7134 *chip; 898 snd_card_saa7134_t *chip;
751 int err; 899 int err;
752 static snd_device_ops_t ops = { 900 static snd_device_ops_t ops = {
753 .dev_free = snd_saa7134_dev_free, 901 .dev_free = snd_saa7134_dev_free,
@@ -757,14 +905,16 @@ int alsa_card_saa7134_create(struct saa7134_dev *saadev)
757 return -ENODEV; 905 return -ENODEV;
758 if (!enable[dev]) 906 if (!enable[dev])
759 return -ENODEV; 907 return -ENODEV;
908
760 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 909 card = snd_card_new(index[dev], id[dev], THIS_MODULE,
761 sizeof(struct snd_card_saa7134)); 910 0);
762 if (card == NULL) 911 if (card == NULL)
763 return -ENOMEM; 912 return -ENOMEM;
764 913
765 strcpy(card->driver, "SAA7134"); 914 strcpy(card->driver, "SAA7134");
766 915
767 /* Card "creation" */ 916 /* Card "creation" */
917
768 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); 918 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
769 if (chip == NULL) { 919 if (chip == NULL) {
770 return -ENOMEM; 920 return -ENOMEM;
@@ -775,6 +925,7 @@ int alsa_card_saa7134_create(struct saa7134_dev *saadev)
775 chip->saadev = saadev; 925 chip->saadev = saadev;
776 926
777 chip->card = card; 927 chip->card = card;
928
778 chip->pci = saadev->pci; 929 chip->pci = saadev->pci;
779 chip->irq = saadev->pci->irq; 930 chip->irq = saadev->pci->irq;
780 chip->iobase = pci_resource_start(saadev->pci, 0); 931 chip->iobase = pci_resource_start(saadev->pci, 0);
@@ -784,12 +935,12 @@ int alsa_card_saa7134_create(struct saa7134_dev *saadev)
784 return err; 935 return err;
785 } 936 }
786 937
787
788 if ((err = snd_card_saa7134_new_mixer(chip)) < 0) 938 if ((err = snd_card_saa7134_new_mixer(chip)) < 0)
789 goto __nodev; 939 goto __nodev;
790 940
791 if ((err = snd_card_saa7134_pcm(chip, 0)) < 0) 941 if ((err = snd_card_saa7134_pcm(chip, 0)) < 0)
792 goto __nodev; 942 goto __nodev;
943
793 spin_lock_init(&chip->mixer_lock); 944 spin_lock_init(&chip->mixer_lock);
794 945
795 snd_card_set_dev(card, &chip->pci->dev); 946 snd_card_set_dev(card, &chip->pci->dev);
@@ -800,7 +951,6 @@ int alsa_card_saa7134_create(struct saa7134_dev *saadev)
800 sprintf(card->longname, "%s at 0x%lx irq %d", 951 sprintf(card->longname, "%s at 0x%lx irq %d",
801 card->shortname, chip->iobase, chip->irq); 952 card->shortname, chip->iobase, chip->irq);
802 953
803
804 if ((err = snd_card_register(card)) == 0) { 954 if ((err = snd_card_register(card)) == 0) {
805 snd_saa7134_cards[dev] = card; 955 snd_saa7134_cards[dev] = card;
806 return 0; 956 return 0;