Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/sound/mips/au1x00.c
10814 views
1
/*
2
* BRIEF MODULE DESCRIPTION
3
* Driver for AMD Au1000 MIPS Processor, AC'97 Sound Port
4
*
5
* Copyright 2004 Cooper Street Innovations Inc.
6
* Author: Charles Eidsness <[email protected]>
7
*
8
* This program is free software; you can redistribute it and/or modify it
9
* under the terms of the GNU General Public License as published by the
10
* Free Software Foundation; either version 2 of the License, or (at your
11
* option) any later version.
12
*
13
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
14
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
15
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
16
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
19
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
*
24
* You should have received a copy of the GNU General Public License along
25
* with this program; if not, write to the Free Software Foundation, Inc.,
26
* 675 Mass Ave, Cambridge, MA 02139, USA.
27
*
28
* History:
29
*
30
* 2004-09-09 Charles Eidsness -- Original verion -- based on
31
* sa11xx-uda1341.c ALSA driver and the
32
* au1000.c OSS driver.
33
* 2004-09-09 Matt Porter -- Added support for ALSA 1.0.6
34
*
35
*/
36
37
#include <linux/ioport.h>
38
#include <linux/interrupt.h>
39
#include <linux/init.h>
40
#include <linux/slab.h>
41
#include <sound/core.h>
42
#include <sound/initval.h>
43
#include <sound/pcm.h>
44
#include <sound/pcm_params.h>
45
#include <sound/ac97_codec.h>
46
#include <asm/mach-au1x00/au1000.h>
47
#include <asm/mach-au1x00/au1000_dma.h>
48
49
MODULE_AUTHOR("Charles Eidsness <[email protected]>");
50
MODULE_DESCRIPTION("Au1000 AC'97 ALSA Driver");
51
MODULE_LICENSE("GPL");
52
MODULE_SUPPORTED_DEVICE("{{AMD,Au1000 AC'97}}");
53
54
#define PLAYBACK 0
55
#define CAPTURE 1
56
#define AC97_SLOT_3 0x01
57
#define AC97_SLOT_4 0x02
58
#define AC97_SLOT_6 0x08
59
#define AC97_CMD_IRQ 31
60
#define READ 0
61
#define WRITE 1
62
#define READ_WAIT 2
63
#define RW_DONE 3
64
65
struct au1000_period
66
{
67
u32 start;
68
u32 relative_end; /*realtive to start of buffer*/
69
struct au1000_period * next;
70
};
71
72
/*Au1000 AC97 Port Control Reisters*/
73
struct au1000_ac97_reg {
74
u32 volatile config;
75
u32 volatile status;
76
u32 volatile data;
77
u32 volatile cmd;
78
u32 volatile cntrl;
79
};
80
81
struct audio_stream {
82
struct snd_pcm_substream *substream;
83
int dma;
84
spinlock_t dma_lock;
85
struct au1000_period * buffer;
86
unsigned int period_size;
87
unsigned int periods;
88
};
89
90
struct snd_au1000 {
91
struct snd_card *card;
92
struct au1000_ac97_reg volatile *ac97_ioport;
93
94
struct resource *ac97_res_port;
95
spinlock_t ac97_lock;
96
struct snd_ac97 *ac97;
97
98
struct snd_pcm *pcm;
99
struct audio_stream *stream[2]; /* playback & capture */
100
};
101
102
/*--------------------------- Local Functions --------------------------------*/
103
static void
104
au1000_set_ac97_xmit_slots(struct snd_au1000 *au1000, long xmit_slots)
105
{
106
u32 volatile ac97_config;
107
108
spin_lock(&au1000->ac97_lock);
109
ac97_config = au1000->ac97_ioport->config;
110
ac97_config = ac97_config & ~AC97C_XMIT_SLOTS_MASK;
111
ac97_config |= (xmit_slots << AC97C_XMIT_SLOTS_BIT);
112
au1000->ac97_ioport->config = ac97_config;
113
spin_unlock(&au1000->ac97_lock);
114
}
115
116
static void
117
au1000_set_ac97_recv_slots(struct snd_au1000 *au1000, long recv_slots)
118
{
119
u32 volatile ac97_config;
120
121
spin_lock(&au1000->ac97_lock);
122
ac97_config = au1000->ac97_ioport->config;
123
ac97_config = ac97_config & ~AC97C_RECV_SLOTS_MASK;
124
ac97_config |= (recv_slots << AC97C_RECV_SLOTS_BIT);
125
au1000->ac97_ioport->config = ac97_config;
126
spin_unlock(&au1000->ac97_lock);
127
}
128
129
130
static void
131
au1000_release_dma_link(struct audio_stream *stream)
132
{
133
struct au1000_period * pointer;
134
struct au1000_period * pointer_next;
135
136
stream->period_size = 0;
137
stream->periods = 0;
138
pointer = stream->buffer;
139
if (! pointer)
140
return;
141
do {
142
pointer_next = pointer->next;
143
kfree(pointer);
144
pointer = pointer_next;
145
} while (pointer != stream->buffer);
146
stream->buffer = NULL;
147
}
148
149
static int
150
au1000_setup_dma_link(struct audio_stream *stream, unsigned int period_bytes,
151
unsigned int periods)
152
{
153
struct snd_pcm_substream *substream = stream->substream;
154
struct snd_pcm_runtime *runtime = substream->runtime;
155
struct au1000_period *pointer;
156
unsigned long dma_start;
157
int i;
158
159
dma_start = virt_to_phys(runtime->dma_area);
160
161
if (stream->period_size == period_bytes &&
162
stream->periods == periods)
163
return 0; /* not changed */
164
165
au1000_release_dma_link(stream);
166
167
stream->period_size = period_bytes;
168
stream->periods = periods;
169
170
stream->buffer = kmalloc(sizeof(struct au1000_period), GFP_KERNEL);
171
if (! stream->buffer)
172
return -ENOMEM;
173
pointer = stream->buffer;
174
for (i = 0; i < periods; i++) {
175
pointer->start = (u32)(dma_start + (i * period_bytes));
176
pointer->relative_end = (u32) (((i+1) * period_bytes) - 0x1);
177
if (i < periods - 1) {
178
pointer->next = kmalloc(sizeof(struct au1000_period), GFP_KERNEL);
179
if (! pointer->next) {
180
au1000_release_dma_link(stream);
181
return -ENOMEM;
182
}
183
pointer = pointer->next;
184
}
185
}
186
pointer->next = stream->buffer;
187
return 0;
188
}
189
190
static void
191
au1000_dma_stop(struct audio_stream *stream)
192
{
193
if (snd_BUG_ON(!stream->buffer))
194
return;
195
disable_dma(stream->dma);
196
}
197
198
static void
199
au1000_dma_start(struct audio_stream *stream)
200
{
201
if (snd_BUG_ON(!stream->buffer))
202
return;
203
204
init_dma(stream->dma);
205
if (get_dma_active_buffer(stream->dma) == 0) {
206
clear_dma_done0(stream->dma);
207
set_dma_addr0(stream->dma, stream->buffer->start);
208
set_dma_count0(stream->dma, stream->period_size >> 1);
209
set_dma_addr1(stream->dma, stream->buffer->next->start);
210
set_dma_count1(stream->dma, stream->period_size >> 1);
211
} else {
212
clear_dma_done1(stream->dma);
213
set_dma_addr1(stream->dma, stream->buffer->start);
214
set_dma_count1(stream->dma, stream->period_size >> 1);
215
set_dma_addr0(stream->dma, stream->buffer->next->start);
216
set_dma_count0(stream->dma, stream->period_size >> 1);
217
}
218
enable_dma_buffers(stream->dma);
219
start_dma(stream->dma);
220
}
221
222
static irqreturn_t
223
au1000_dma_interrupt(int irq, void *dev_id)
224
{
225
struct audio_stream *stream = (struct audio_stream *) dev_id;
226
struct snd_pcm_substream *substream = stream->substream;
227
228
spin_lock(&stream->dma_lock);
229
switch (get_dma_buffer_done(stream->dma)) {
230
case DMA_D0:
231
stream->buffer = stream->buffer->next;
232
clear_dma_done0(stream->dma);
233
set_dma_addr0(stream->dma, stream->buffer->next->start);
234
set_dma_count0(stream->dma, stream->period_size >> 1);
235
enable_dma_buffer0(stream->dma);
236
break;
237
case DMA_D1:
238
stream->buffer = stream->buffer->next;
239
clear_dma_done1(stream->dma);
240
set_dma_addr1(stream->dma, stream->buffer->next->start);
241
set_dma_count1(stream->dma, stream->period_size >> 1);
242
enable_dma_buffer1(stream->dma);
243
break;
244
case (DMA_D0 | DMA_D1):
245
printk(KERN_ERR "DMA %d missed interrupt.\n",stream->dma);
246
au1000_dma_stop(stream);
247
au1000_dma_start(stream);
248
break;
249
case (~DMA_D0 & ~DMA_D1):
250
printk(KERN_ERR "DMA %d empty irq.\n",stream->dma);
251
}
252
spin_unlock(&stream->dma_lock);
253
snd_pcm_period_elapsed(substream);
254
return IRQ_HANDLED;
255
}
256
257
/*-------------------------- PCM Audio Streams -------------------------------*/
258
259
static unsigned int rates[] = {8000, 11025, 16000, 22050};
260
static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
261
.count = ARRAY_SIZE(rates),
262
.list = rates,
263
.mask = 0,
264
};
265
266
static struct snd_pcm_hardware snd_au1000_hw =
267
{
268
.info = (SNDRV_PCM_INFO_INTERLEAVED | \
269
SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
270
.formats = SNDRV_PCM_FMTBIT_S16_LE,
271
.rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
272
SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050),
273
.rate_min = 8000,
274
.rate_max = 22050,
275
.channels_min = 1,
276
.channels_max = 2,
277
.buffer_bytes_max = 128*1024,
278
.period_bytes_min = 32,
279
.period_bytes_max = 16*1024,
280
.periods_min = 8,
281
.periods_max = 255,
282
.fifo_size = 16,
283
};
284
285
static int
286
snd_au1000_playback_open(struct snd_pcm_substream *substream)
287
{
288
struct snd_au1000 *au1000 = substream->pcm->private_data;
289
290
au1000->stream[PLAYBACK]->substream = substream;
291
au1000->stream[PLAYBACK]->buffer = NULL;
292
substream->private_data = au1000->stream[PLAYBACK];
293
substream->runtime->hw = snd_au1000_hw;
294
return (snd_pcm_hw_constraint_list(substream->runtime, 0,
295
SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates) < 0);
296
}
297
298
static int
299
snd_au1000_capture_open(struct snd_pcm_substream *substream)
300
{
301
struct snd_au1000 *au1000 = substream->pcm->private_data;
302
303
au1000->stream[CAPTURE]->substream = substream;
304
au1000->stream[CAPTURE]->buffer = NULL;
305
substream->private_data = au1000->stream[CAPTURE];
306
substream->runtime->hw = snd_au1000_hw;
307
return (snd_pcm_hw_constraint_list(substream->runtime, 0,
308
SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates) < 0);
309
}
310
311
static int
312
snd_au1000_playback_close(struct snd_pcm_substream *substream)
313
{
314
struct snd_au1000 *au1000 = substream->pcm->private_data;
315
316
au1000->stream[PLAYBACK]->substream = NULL;
317
return 0;
318
}
319
320
static int
321
snd_au1000_capture_close(struct snd_pcm_substream *substream)
322
{
323
struct snd_au1000 *au1000 = substream->pcm->private_data;
324
325
au1000->stream[CAPTURE]->substream = NULL;
326
return 0;
327
}
328
329
static int
330
snd_au1000_hw_params(struct snd_pcm_substream *substream,
331
struct snd_pcm_hw_params *hw_params)
332
{
333
struct audio_stream *stream = substream->private_data;
334
int err;
335
336
err = snd_pcm_lib_malloc_pages(substream,
337
params_buffer_bytes(hw_params));
338
if (err < 0)
339
return err;
340
return au1000_setup_dma_link(stream,
341
params_period_bytes(hw_params),
342
params_periods(hw_params));
343
}
344
345
static int
346
snd_au1000_hw_free(struct snd_pcm_substream *substream)
347
{
348
struct audio_stream *stream = substream->private_data;
349
au1000_release_dma_link(stream);
350
return snd_pcm_lib_free_pages(substream);
351
}
352
353
static int
354
snd_au1000_playback_prepare(struct snd_pcm_substream *substream)
355
{
356
struct snd_au1000 *au1000 = substream->pcm->private_data;
357
struct snd_pcm_runtime *runtime = substream->runtime;
358
359
if (runtime->channels == 1)
360
au1000_set_ac97_xmit_slots(au1000, AC97_SLOT_4);
361
else
362
au1000_set_ac97_xmit_slots(au1000, AC97_SLOT_3 | AC97_SLOT_4);
363
snd_ac97_set_rate(au1000->ac97, AC97_PCM_FRONT_DAC_RATE, runtime->rate);
364
return 0;
365
}
366
367
static int
368
snd_au1000_capture_prepare(struct snd_pcm_substream *substream)
369
{
370
struct snd_au1000 *au1000 = substream->pcm->private_data;
371
struct snd_pcm_runtime *runtime = substream->runtime;
372
373
if (runtime->channels == 1)
374
au1000_set_ac97_recv_slots(au1000, AC97_SLOT_4);
375
else
376
au1000_set_ac97_recv_slots(au1000, AC97_SLOT_3 | AC97_SLOT_4);
377
snd_ac97_set_rate(au1000->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate);
378
return 0;
379
}
380
381
static int
382
snd_au1000_trigger(struct snd_pcm_substream *substream, int cmd)
383
{
384
struct audio_stream *stream = substream->private_data;
385
int err = 0;
386
387
spin_lock(&stream->dma_lock);
388
switch (cmd) {
389
case SNDRV_PCM_TRIGGER_START:
390
au1000_dma_start(stream);
391
break;
392
case SNDRV_PCM_TRIGGER_STOP:
393
au1000_dma_stop(stream);
394
break;
395
default:
396
err = -EINVAL;
397
break;
398
}
399
spin_unlock(&stream->dma_lock);
400
return err;
401
}
402
403
static snd_pcm_uframes_t
404
snd_au1000_pointer(struct snd_pcm_substream *substream)
405
{
406
struct audio_stream *stream = substream->private_data;
407
struct snd_pcm_runtime *runtime = substream->runtime;
408
long location;
409
410
spin_lock(&stream->dma_lock);
411
location = get_dma_residue(stream->dma);
412
spin_unlock(&stream->dma_lock);
413
location = stream->buffer->relative_end - location;
414
if (location == -1)
415
location = 0;
416
return bytes_to_frames(runtime,location);
417
}
418
419
static struct snd_pcm_ops snd_card_au1000_playback_ops = {
420
.open = snd_au1000_playback_open,
421
.close = snd_au1000_playback_close,
422
.ioctl = snd_pcm_lib_ioctl,
423
.hw_params = snd_au1000_hw_params,
424
.hw_free = snd_au1000_hw_free,
425
.prepare = snd_au1000_playback_prepare,
426
.trigger = snd_au1000_trigger,
427
.pointer = snd_au1000_pointer,
428
};
429
430
static struct snd_pcm_ops snd_card_au1000_capture_ops = {
431
.open = snd_au1000_capture_open,
432
.close = snd_au1000_capture_close,
433
.ioctl = snd_pcm_lib_ioctl,
434
.hw_params = snd_au1000_hw_params,
435
.hw_free = snd_au1000_hw_free,
436
.prepare = snd_au1000_capture_prepare,
437
.trigger = snd_au1000_trigger,
438
.pointer = snd_au1000_pointer,
439
};
440
441
static int __devinit
442
snd_au1000_pcm_new(struct snd_au1000 *au1000)
443
{
444
struct snd_pcm *pcm;
445
int err;
446
unsigned long flags;
447
448
if ((err = snd_pcm_new(au1000->card, "AU1000 AC97 PCM", 0, 1, 1, &pcm)) < 0)
449
return err;
450
451
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
452
snd_dma_continuous_data(GFP_KERNEL), 128*1024, 128*1024);
453
454
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
455
&snd_card_au1000_playback_ops);
456
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
457
&snd_card_au1000_capture_ops);
458
459
pcm->private_data = au1000;
460
pcm->info_flags = 0;
461
strcpy(pcm->name, "Au1000 AC97 PCM");
462
463
spin_lock_init(&au1000->stream[PLAYBACK]->dma_lock);
464
spin_lock_init(&au1000->stream[CAPTURE]->dma_lock);
465
466
flags = claim_dma_lock();
467
if ((au1000->stream[PLAYBACK]->dma = request_au1000_dma(DMA_ID_AC97C_TX,
468
"AC97 TX", au1000_dma_interrupt, IRQF_DISABLED,
469
au1000->stream[PLAYBACK])) < 0) {
470
release_dma_lock(flags);
471
return -EBUSY;
472
}
473
if ((au1000->stream[CAPTURE]->dma = request_au1000_dma(DMA_ID_AC97C_RX,
474
"AC97 RX", au1000_dma_interrupt, IRQF_DISABLED,
475
au1000->stream[CAPTURE])) < 0){
476
release_dma_lock(flags);
477
return -EBUSY;
478
}
479
/* enable DMA coherency in read/write DMA channels */
480
set_dma_mode(au1000->stream[PLAYBACK]->dma,
481
get_dma_mode(au1000->stream[PLAYBACK]->dma) & ~DMA_NC);
482
set_dma_mode(au1000->stream[CAPTURE]->dma,
483
get_dma_mode(au1000->stream[CAPTURE]->dma) & ~DMA_NC);
484
release_dma_lock(flags);
485
au1000->pcm = pcm;
486
return 0;
487
}
488
489
490
/*-------------------------- AC97 CODEC Control ------------------------------*/
491
492
static unsigned short
493
snd_au1000_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
494
{
495
struct snd_au1000 *au1000 = ac97->private_data;
496
u32 volatile cmd;
497
u16 volatile data;
498
int i;
499
500
spin_lock(&au1000->ac97_lock);
501
/* would rather use the interrupt than this polling but it works and I can't
502
get the interrupt driven case to work efficiently */
503
for (i = 0; i < 0x5000; i++)
504
if (!(au1000->ac97_ioport->status & AC97C_CP))
505
break;
506
if (i == 0x5000)
507
printk(KERN_ERR "au1000 AC97: AC97 command read timeout\n");
508
509
cmd = (u32) reg & AC97C_INDEX_MASK;
510
cmd |= AC97C_READ;
511
au1000->ac97_ioport->cmd = cmd;
512
513
/* now wait for the data */
514
for (i = 0; i < 0x5000; i++)
515
if (!(au1000->ac97_ioport->status & AC97C_CP))
516
break;
517
if (i == 0x5000) {
518
printk(KERN_ERR "au1000 AC97: AC97 command read timeout\n");
519
spin_unlock(&au1000->ac97_lock);
520
return 0;
521
}
522
523
data = au1000->ac97_ioport->cmd & 0xffff;
524
spin_unlock(&au1000->ac97_lock);
525
526
return data;
527
528
}
529
530
531
static void
532
snd_au1000_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
533
{
534
struct snd_au1000 *au1000 = ac97->private_data;
535
u32 cmd;
536
int i;
537
538
spin_lock(&au1000->ac97_lock);
539
/* would rather use the interrupt than this polling but it works and I can't
540
get the interrupt driven case to work efficiently */
541
for (i = 0; i < 0x5000; i++)
542
if (!(au1000->ac97_ioport->status & AC97C_CP))
543
break;
544
if (i == 0x5000)
545
printk(KERN_ERR "au1000 AC97: AC97 command write timeout\n");
546
547
cmd = (u32) reg & AC97C_INDEX_MASK;
548
cmd &= ~AC97C_READ;
549
cmd |= ((u32) val << AC97C_WD_BIT);
550
au1000->ac97_ioport->cmd = cmd;
551
spin_unlock(&au1000->ac97_lock);
552
}
553
554
static int __devinit
555
snd_au1000_ac97_new(struct snd_au1000 *au1000)
556
{
557
int err;
558
struct snd_ac97_bus *pbus;
559
struct snd_ac97_template ac97;
560
static struct snd_ac97_bus_ops ops = {
561
.write = snd_au1000_ac97_write,
562
.read = snd_au1000_ac97_read,
563
};
564
565
if ((au1000->ac97_res_port = request_mem_region(CPHYSADDR(AC97C_CONFIG),
566
0x100000, "Au1x00 AC97")) == NULL) {
567
snd_printk(KERN_ERR "ALSA AC97: can't grap AC97 port\n");
568
return -EBUSY;
569
}
570
au1000->ac97_ioport = (struct au1000_ac97_reg *)
571
KSEG1ADDR(au1000->ac97_res_port->start);
572
573
spin_lock_init(&au1000->ac97_lock);
574
575
/* configure pins for AC'97
576
TODO: move to board_setup.c */
577
au_writel(au_readl(SYS_PINFUNC) & ~0x02, SYS_PINFUNC);
578
579
/* Initialise Au1000's AC'97 Control Block */
580
au1000->ac97_ioport->cntrl = AC97C_RS | AC97C_CE;
581
udelay(10);
582
au1000->ac97_ioport->cntrl = AC97C_CE;
583
udelay(10);
584
585
/* Initialise External CODEC -- cold reset */
586
au1000->ac97_ioport->config = AC97C_RESET;
587
udelay(10);
588
au1000->ac97_ioport->config = 0x0;
589
mdelay(5);
590
591
/* Initialise AC97 middle-layer */
592
if ((err = snd_ac97_bus(au1000->card, 0, &ops, au1000, &pbus)) < 0)
593
return err;
594
595
memset(&ac97, 0, sizeof(ac97));
596
ac97.private_data = au1000;
597
if ((err = snd_ac97_mixer(pbus, &ac97, &au1000->ac97)) < 0)
598
return err;
599
600
return 0;
601
}
602
603
/*------------------------------ Setup / Destroy ----------------------------*/
604
605
void
606
snd_au1000_free(struct snd_card *card)
607
{
608
struct snd_au1000 *au1000 = card->private_data;
609
610
if (au1000->ac97_res_port) {
611
/* put internal AC97 block into reset */
612
au1000->ac97_ioport->cntrl = AC97C_RS;
613
au1000->ac97_ioport = NULL;
614
release_and_free_resource(au1000->ac97_res_port);
615
}
616
617
if (au1000->stream[PLAYBACK]) {
618
if (au1000->stream[PLAYBACK]->dma >= 0)
619
free_au1000_dma(au1000->stream[PLAYBACK]->dma);
620
kfree(au1000->stream[PLAYBACK]);
621
}
622
623
if (au1000->stream[CAPTURE]) {
624
if (au1000->stream[CAPTURE]->dma >= 0)
625
free_au1000_dma(au1000->stream[CAPTURE]->dma);
626
kfree(au1000->stream[CAPTURE]);
627
}
628
}
629
630
631
static struct snd_card *au1000_card;
632
633
static int __init
634
au1000_init(void)
635
{
636
int err;
637
struct snd_card *card;
638
struct snd_au1000 *au1000;
639
640
err = snd_card_create(-1, "AC97", THIS_MODULE,
641
sizeof(struct snd_au1000), &card);
642
if (err < 0)
643
return err;
644
645
card->private_free = snd_au1000_free;
646
au1000 = card->private_data;
647
au1000->card = card;
648
649
au1000->stream[PLAYBACK] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL);
650
au1000->stream[CAPTURE ] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL);
651
/* so that snd_au1000_free will work as intended */
652
au1000->ac97_res_port = NULL;
653
if (au1000->stream[PLAYBACK])
654
au1000->stream[PLAYBACK]->dma = -1;
655
if (au1000->stream[CAPTURE ])
656
au1000->stream[CAPTURE ]->dma = -1;
657
658
if (au1000->stream[PLAYBACK] == NULL ||
659
au1000->stream[CAPTURE ] == NULL) {
660
snd_card_free(card);
661
return -ENOMEM;
662
}
663
664
if ((err = snd_au1000_ac97_new(au1000)) < 0 ) {
665
snd_card_free(card);
666
return err;
667
}
668
669
if ((err = snd_au1000_pcm_new(au1000)) < 0) {
670
snd_card_free(card);
671
return err;
672
}
673
674
strcpy(card->driver, "Au1000-AC97");
675
strcpy(card->shortname, "AMD Au1000-AC97");
676
sprintf(card->longname, "AMD Au1000--AC97 ALSA Driver");
677
678
if ((err = snd_card_register(card)) < 0) {
679
snd_card_free(card);
680
return err;
681
}
682
683
printk(KERN_INFO "ALSA AC97: Driver Initialized\n");
684
au1000_card = card;
685
return 0;
686
}
687
688
static void __exit au1000_exit(void)
689
{
690
snd_card_free(au1000_card);
691
}
692
693
module_init(au1000_init);
694
module_exit(au1000_exit);
695
696
697