Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/mips/sgio2audio.c
26377 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* Sound driver for Silicon Graphics O2 Workstations A/V board audio.
4
*
5
* Copyright 2003 Vivien Chappelier <[email protected]>
6
* Copyright 2008 Thomas Bogendoerfer <[email protected]>
7
* Mxier part taken from mace_audio.c:
8
* Copyright 2007 Thorben Jändling <[email protected]>
9
*/
10
11
#include <linux/init.h>
12
#include <linux/delay.h>
13
#include <linux/spinlock.h>
14
#include <linux/interrupt.h>
15
#include <linux/dma-mapping.h>
16
#include <linux/platform_device.h>
17
#include <linux/io.h>
18
#include <linux/slab.h>
19
#include <linux/string.h>
20
#include <linux/module.h>
21
22
#include <asm/ip32/ip32_ints.h>
23
#include <asm/ip32/mace.h>
24
25
#include <sound/core.h>
26
#include <sound/control.h>
27
#include <sound/pcm.h>
28
#define SNDRV_GET_ID
29
#include <sound/initval.h>
30
#include <sound/ad1843.h>
31
32
33
MODULE_AUTHOR("Vivien Chappelier <[email protected]>");
34
MODULE_DESCRIPTION("SGI O2 Audio");
35
MODULE_LICENSE("GPL");
36
37
static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
38
static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
39
40
module_param(index, int, 0444);
41
MODULE_PARM_DESC(index, "Index value for SGI O2 soundcard.");
42
module_param(id, charp, 0444);
43
MODULE_PARM_DESC(id, "ID string for SGI O2 soundcard.");
44
45
46
#define AUDIO_CONTROL_RESET BIT(0) /* 1: reset audio interface */
47
#define AUDIO_CONTROL_CODEC_PRESENT BIT(1) /* 1: codec detected */
48
49
#define CODEC_CONTROL_WORD_SHIFT 0
50
#define CODEC_CONTROL_READ BIT(16)
51
#define CODEC_CONTROL_ADDRESS_SHIFT 17
52
53
#define CHANNEL_CONTROL_RESET BIT(10) /* 1: reset channel */
54
#define CHANNEL_DMA_ENABLE BIT(9) /* 1: enable DMA transfer */
55
#define CHANNEL_INT_THRESHOLD_DISABLED (0 << 5) /* interrupt disabled */
56
#define CHANNEL_INT_THRESHOLD_25 (1 << 5) /* int on buffer >25% full */
57
#define CHANNEL_INT_THRESHOLD_50 (2 << 5) /* int on buffer >50% full */
58
#define CHANNEL_INT_THRESHOLD_75 (3 << 5) /* int on buffer >75% full */
59
#define CHANNEL_INT_THRESHOLD_EMPTY (4 << 5) /* int on buffer empty */
60
#define CHANNEL_INT_THRESHOLD_NOT_EMPTY (5 << 5) /* int on buffer !empty */
61
#define CHANNEL_INT_THRESHOLD_FULL (6 << 5) /* int on buffer empty */
62
#define CHANNEL_INT_THRESHOLD_NOT_FULL (7 << 5) /* int on buffer !empty */
63
64
#define CHANNEL_RING_SHIFT 12
65
#define CHANNEL_RING_SIZE (1 << CHANNEL_RING_SHIFT)
66
#define CHANNEL_RING_MASK (CHANNEL_RING_SIZE - 1)
67
68
#define CHANNEL_LEFT_SHIFT 40
69
#define CHANNEL_RIGHT_SHIFT 8
70
71
struct snd_sgio2audio_chan {
72
int idx;
73
struct snd_pcm_substream *substream;
74
int pos;
75
snd_pcm_uframes_t size;
76
spinlock_t lock;
77
};
78
79
/* definition of the chip-specific record */
80
struct snd_sgio2audio {
81
struct snd_card *card;
82
83
/* codec */
84
struct snd_ad1843 ad1843;
85
spinlock_t ad1843_lock;
86
87
/* channels */
88
struct snd_sgio2audio_chan channel[3];
89
90
/* resources */
91
void *ring_base;
92
dma_addr_t ring_base_dma;
93
};
94
95
/* AD1843 access */
96
97
/*
98
* read_ad1843_reg returns the current contents of a 16 bit AD1843 register.
99
*
100
* Returns unsigned register value on success, -errno on failure.
101
*/
102
static int read_ad1843_reg(void *priv, int reg)
103
{
104
struct snd_sgio2audio *chip = priv;
105
int val;
106
unsigned long flags;
107
108
spin_lock_irqsave(&chip->ad1843_lock, flags);
109
110
writeq((reg << CODEC_CONTROL_ADDRESS_SHIFT) |
111
CODEC_CONTROL_READ, &mace->perif.audio.codec_control);
112
wmb();
113
val = readq(&mace->perif.audio.codec_control); /* flush bus */
114
udelay(200);
115
116
val = readq(&mace->perif.audio.codec_read);
117
118
spin_unlock_irqrestore(&chip->ad1843_lock, flags);
119
return val;
120
}
121
122
/*
123
* write_ad1843_reg writes the specified value to a 16 bit AD1843 register.
124
*/
125
static int write_ad1843_reg(void *priv, int reg, int word)
126
{
127
struct snd_sgio2audio *chip = priv;
128
int val;
129
unsigned long flags;
130
131
spin_lock_irqsave(&chip->ad1843_lock, flags);
132
133
writeq((reg << CODEC_CONTROL_ADDRESS_SHIFT) |
134
(word << CODEC_CONTROL_WORD_SHIFT),
135
&mace->perif.audio.codec_control);
136
wmb();
137
val = readq(&mace->perif.audio.codec_control); /* flush bus */
138
udelay(200);
139
140
spin_unlock_irqrestore(&chip->ad1843_lock, flags);
141
return 0;
142
}
143
144
static int sgio2audio_gain_info(struct snd_kcontrol *kcontrol,
145
struct snd_ctl_elem_info *uinfo)
146
{
147
struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol);
148
149
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
150
uinfo->count = 2;
151
uinfo->value.integer.min = 0;
152
uinfo->value.integer.max = ad1843_get_gain_max(&chip->ad1843,
153
(int)kcontrol->private_value);
154
return 0;
155
}
156
157
static int sgio2audio_gain_get(struct snd_kcontrol *kcontrol,
158
struct snd_ctl_elem_value *ucontrol)
159
{
160
struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol);
161
int vol;
162
163
vol = ad1843_get_gain(&chip->ad1843, (int)kcontrol->private_value);
164
165
ucontrol->value.integer.value[0] = (vol >> 8) & 0xFF;
166
ucontrol->value.integer.value[1] = vol & 0xFF;
167
168
return 0;
169
}
170
171
static int sgio2audio_gain_put(struct snd_kcontrol *kcontrol,
172
struct snd_ctl_elem_value *ucontrol)
173
{
174
struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol);
175
int newvol, oldvol;
176
177
oldvol = ad1843_get_gain(&chip->ad1843, kcontrol->private_value);
178
newvol = (ucontrol->value.integer.value[0] << 8) |
179
ucontrol->value.integer.value[1];
180
181
newvol = ad1843_set_gain(&chip->ad1843, kcontrol->private_value,
182
newvol);
183
184
return newvol != oldvol;
185
}
186
187
static int sgio2audio_source_info(struct snd_kcontrol *kcontrol,
188
struct snd_ctl_elem_info *uinfo)
189
{
190
static const char * const texts[3] = {
191
"Cam Mic", "Mic", "Line"
192
};
193
return snd_ctl_enum_info(uinfo, 1, 3, texts);
194
}
195
196
static int sgio2audio_source_get(struct snd_kcontrol *kcontrol,
197
struct snd_ctl_elem_value *ucontrol)
198
{
199
struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol);
200
201
ucontrol->value.enumerated.item[0] = ad1843_get_recsrc(&chip->ad1843);
202
return 0;
203
}
204
205
static int sgio2audio_source_put(struct snd_kcontrol *kcontrol,
206
struct snd_ctl_elem_value *ucontrol)
207
{
208
struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol);
209
int newsrc, oldsrc;
210
211
oldsrc = ad1843_get_recsrc(&chip->ad1843);
212
newsrc = ad1843_set_recsrc(&chip->ad1843,
213
ucontrol->value.enumerated.item[0]);
214
215
return newsrc != oldsrc;
216
}
217
218
/* dac1/pcm0 mixer control */
219
static const struct snd_kcontrol_new sgio2audio_ctrl_pcm0 = {
220
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
221
.name = "PCM Playback Volume",
222
.index = 0,
223
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
224
.private_value = AD1843_GAIN_PCM_0,
225
.info = sgio2audio_gain_info,
226
.get = sgio2audio_gain_get,
227
.put = sgio2audio_gain_put,
228
};
229
230
/* dac2/pcm1 mixer control */
231
static const struct snd_kcontrol_new sgio2audio_ctrl_pcm1 = {
232
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
233
.name = "PCM Playback Volume",
234
.index = 1,
235
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
236
.private_value = AD1843_GAIN_PCM_1,
237
.info = sgio2audio_gain_info,
238
.get = sgio2audio_gain_get,
239
.put = sgio2audio_gain_put,
240
};
241
242
/* record level mixer control */
243
static const struct snd_kcontrol_new sgio2audio_ctrl_reclevel = {
244
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
245
.name = "Capture Volume",
246
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
247
.private_value = AD1843_GAIN_RECLEV,
248
.info = sgio2audio_gain_info,
249
.get = sgio2audio_gain_get,
250
.put = sgio2audio_gain_put,
251
};
252
253
/* record level source control */
254
static const struct snd_kcontrol_new sgio2audio_ctrl_recsource = {
255
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
256
.name = "Capture Source",
257
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
258
.info = sgio2audio_source_info,
259
.get = sgio2audio_source_get,
260
.put = sgio2audio_source_put,
261
};
262
263
/* line mixer control */
264
static const struct snd_kcontrol_new sgio2audio_ctrl_line = {
265
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
266
.name = "Line Playback Volume",
267
.index = 0,
268
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
269
.private_value = AD1843_GAIN_LINE,
270
.info = sgio2audio_gain_info,
271
.get = sgio2audio_gain_get,
272
.put = sgio2audio_gain_put,
273
};
274
275
/* cd mixer control */
276
static const struct snd_kcontrol_new sgio2audio_ctrl_cd = {
277
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
278
.name = "Line Playback Volume",
279
.index = 1,
280
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
281
.private_value = AD1843_GAIN_LINE_2,
282
.info = sgio2audio_gain_info,
283
.get = sgio2audio_gain_get,
284
.put = sgio2audio_gain_put,
285
};
286
287
/* mic mixer control */
288
static const struct snd_kcontrol_new sgio2audio_ctrl_mic = {
289
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
290
.name = "Mic Playback Volume",
291
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
292
.private_value = AD1843_GAIN_MIC,
293
.info = sgio2audio_gain_info,
294
.get = sgio2audio_gain_get,
295
.put = sgio2audio_gain_put,
296
};
297
298
299
static int snd_sgio2audio_new_mixer(struct snd_sgio2audio *chip)
300
{
301
int err;
302
303
err = snd_ctl_add(chip->card,
304
snd_ctl_new1(&sgio2audio_ctrl_pcm0, chip));
305
if (err < 0)
306
return err;
307
308
err = snd_ctl_add(chip->card,
309
snd_ctl_new1(&sgio2audio_ctrl_pcm1, chip));
310
if (err < 0)
311
return err;
312
313
err = snd_ctl_add(chip->card,
314
snd_ctl_new1(&sgio2audio_ctrl_reclevel, chip));
315
if (err < 0)
316
return err;
317
318
err = snd_ctl_add(chip->card,
319
snd_ctl_new1(&sgio2audio_ctrl_recsource, chip));
320
if (err < 0)
321
return err;
322
err = snd_ctl_add(chip->card,
323
snd_ctl_new1(&sgio2audio_ctrl_line, chip));
324
if (err < 0)
325
return err;
326
327
err = snd_ctl_add(chip->card,
328
snd_ctl_new1(&sgio2audio_ctrl_cd, chip));
329
if (err < 0)
330
return err;
331
332
err = snd_ctl_add(chip->card,
333
snd_ctl_new1(&sgio2audio_ctrl_mic, chip));
334
if (err < 0)
335
return err;
336
337
return 0;
338
}
339
340
/* low-level audio interface DMA */
341
342
/* get data out of bounce buffer, count must be a multiple of 32 */
343
/* returns 1 if a period has elapsed */
344
static int snd_sgio2audio_dma_pull_frag(struct snd_sgio2audio *chip,
345
unsigned int ch, unsigned int count)
346
{
347
int ret;
348
unsigned long src_base, src_pos, dst_mask;
349
unsigned char *dst_base;
350
int dst_pos;
351
u64 *src;
352
s16 *dst;
353
u64 x;
354
unsigned long flags;
355
struct snd_pcm_runtime *runtime = chip->channel[ch].substream->runtime;
356
357
spin_lock_irqsave(&chip->channel[ch].lock, flags);
358
359
src_base = (unsigned long) chip->ring_base | (ch << CHANNEL_RING_SHIFT);
360
src_pos = readq(&mace->perif.audio.chan[ch].read_ptr);
361
dst_base = runtime->dma_area;
362
dst_pos = chip->channel[ch].pos;
363
dst_mask = frames_to_bytes(runtime, runtime->buffer_size) - 1;
364
365
/* check if a period has elapsed */
366
chip->channel[ch].size += (count >> 3); /* in frames */
367
ret = chip->channel[ch].size >= runtime->period_size;
368
chip->channel[ch].size %= runtime->period_size;
369
370
while (count) {
371
src = (u64 *)(src_base + src_pos);
372
dst = (s16 *)(dst_base + dst_pos);
373
374
x = *src;
375
dst[0] = (x >> CHANNEL_LEFT_SHIFT) & 0xffff;
376
dst[1] = (x >> CHANNEL_RIGHT_SHIFT) & 0xffff;
377
378
src_pos = (src_pos + sizeof(u64)) & CHANNEL_RING_MASK;
379
dst_pos = (dst_pos + 2 * sizeof(s16)) & dst_mask;
380
count -= sizeof(u64);
381
}
382
383
writeq(src_pos, &mace->perif.audio.chan[ch].read_ptr); /* in bytes */
384
chip->channel[ch].pos = dst_pos;
385
386
spin_unlock_irqrestore(&chip->channel[ch].lock, flags);
387
return ret;
388
}
389
390
/* put some DMA data in bounce buffer, count must be a multiple of 32 */
391
/* returns 1 if a period has elapsed */
392
static int snd_sgio2audio_dma_push_frag(struct snd_sgio2audio *chip,
393
unsigned int ch, unsigned int count)
394
{
395
int ret;
396
s64 l, r;
397
unsigned long dst_base, dst_pos, src_mask;
398
unsigned char *src_base;
399
int src_pos;
400
u64 *dst;
401
s16 *src;
402
unsigned long flags;
403
struct snd_pcm_runtime *runtime = chip->channel[ch].substream->runtime;
404
405
spin_lock_irqsave(&chip->channel[ch].lock, flags);
406
407
dst_base = (unsigned long)chip->ring_base | (ch << CHANNEL_RING_SHIFT);
408
dst_pos = readq(&mace->perif.audio.chan[ch].write_ptr);
409
src_base = runtime->dma_area;
410
src_pos = chip->channel[ch].pos;
411
src_mask = frames_to_bytes(runtime, runtime->buffer_size) - 1;
412
413
/* check if a period has elapsed */
414
chip->channel[ch].size += (count >> 3); /* in frames */
415
ret = chip->channel[ch].size >= runtime->period_size;
416
chip->channel[ch].size %= runtime->period_size;
417
418
while (count) {
419
src = (s16 *)(src_base + src_pos);
420
dst = (u64 *)(dst_base + dst_pos);
421
422
l = src[0]; /* sign extend */
423
r = src[1]; /* sign extend */
424
425
*dst = ((l & 0x00ffffff) << CHANNEL_LEFT_SHIFT) |
426
((r & 0x00ffffff) << CHANNEL_RIGHT_SHIFT);
427
428
dst_pos = (dst_pos + sizeof(u64)) & CHANNEL_RING_MASK;
429
src_pos = (src_pos + 2 * sizeof(s16)) & src_mask;
430
count -= sizeof(u64);
431
}
432
433
writeq(dst_pos, &mace->perif.audio.chan[ch].write_ptr); /* in bytes */
434
chip->channel[ch].pos = src_pos;
435
436
spin_unlock_irqrestore(&chip->channel[ch].lock, flags);
437
return ret;
438
}
439
440
static int snd_sgio2audio_dma_start(struct snd_pcm_substream *substream)
441
{
442
struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream);
443
struct snd_sgio2audio_chan *chan = substream->runtime->private_data;
444
int ch = chan->idx;
445
446
/* reset DMA channel */
447
writeq(CHANNEL_CONTROL_RESET, &mace->perif.audio.chan[ch].control);
448
udelay(10);
449
writeq(0, &mace->perif.audio.chan[ch].control);
450
451
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
452
/* push a full buffer */
453
snd_sgio2audio_dma_push_frag(chip, ch, CHANNEL_RING_SIZE - 32);
454
}
455
/* set DMA to wake on 50% empty and enable interrupt */
456
writeq(CHANNEL_DMA_ENABLE | CHANNEL_INT_THRESHOLD_50,
457
&mace->perif.audio.chan[ch].control);
458
return 0;
459
}
460
461
static int snd_sgio2audio_dma_stop(struct snd_pcm_substream *substream)
462
{
463
struct snd_sgio2audio_chan *chan = substream->runtime->private_data;
464
465
writeq(0, &mace->perif.audio.chan[chan->idx].control);
466
return 0;
467
}
468
469
static irqreturn_t snd_sgio2audio_dma_in_isr(int irq, void *dev_id)
470
{
471
struct snd_sgio2audio_chan *chan = dev_id;
472
struct snd_pcm_substream *substream;
473
struct snd_sgio2audio *chip;
474
int count, ch;
475
476
substream = chan->substream;
477
chip = snd_pcm_substream_chip(substream);
478
ch = chan->idx;
479
480
/* empty the ring */
481
count = CHANNEL_RING_SIZE -
482
readq(&mace->perif.audio.chan[ch].depth) - 32;
483
if (snd_sgio2audio_dma_pull_frag(chip, ch, count))
484
snd_pcm_period_elapsed(substream);
485
486
return IRQ_HANDLED;
487
}
488
489
static irqreturn_t snd_sgio2audio_dma_out_isr(int irq, void *dev_id)
490
{
491
struct snd_sgio2audio_chan *chan = dev_id;
492
struct snd_pcm_substream *substream;
493
struct snd_sgio2audio *chip;
494
int count, ch;
495
496
substream = chan->substream;
497
chip = snd_pcm_substream_chip(substream);
498
ch = chan->idx;
499
/* fill the ring */
500
count = CHANNEL_RING_SIZE -
501
readq(&mace->perif.audio.chan[ch].depth) - 32;
502
if (snd_sgio2audio_dma_push_frag(chip, ch, count))
503
snd_pcm_period_elapsed(substream);
504
505
return IRQ_HANDLED;
506
}
507
508
static irqreturn_t snd_sgio2audio_error_isr(int irq, void *dev_id)
509
{
510
struct snd_sgio2audio_chan *chan = dev_id;
511
struct snd_pcm_substream *substream;
512
513
substream = chan->substream;
514
snd_sgio2audio_dma_stop(substream);
515
snd_sgio2audio_dma_start(substream);
516
return IRQ_HANDLED;
517
}
518
519
/* PCM part */
520
/* PCM hardware definition */
521
static const struct snd_pcm_hardware snd_sgio2audio_pcm_hw = {
522
.info = (SNDRV_PCM_INFO_MMAP |
523
SNDRV_PCM_INFO_MMAP_VALID |
524
SNDRV_PCM_INFO_INTERLEAVED |
525
SNDRV_PCM_INFO_BLOCK_TRANSFER),
526
.formats = SNDRV_PCM_FMTBIT_S16_BE,
527
.rates = SNDRV_PCM_RATE_8000_48000,
528
.rate_min = 8000,
529
.rate_max = 48000,
530
.channels_min = 2,
531
.channels_max = 2,
532
.buffer_bytes_max = 65536,
533
.period_bytes_min = 32768,
534
.period_bytes_max = 65536,
535
.periods_min = 1,
536
.periods_max = 1024,
537
};
538
539
/* PCM playback open callback */
540
static int snd_sgio2audio_playback1_open(struct snd_pcm_substream *substream)
541
{
542
struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream);
543
struct snd_pcm_runtime *runtime = substream->runtime;
544
545
runtime->hw = snd_sgio2audio_pcm_hw;
546
runtime->private_data = &chip->channel[1];
547
return 0;
548
}
549
550
static int snd_sgio2audio_playback2_open(struct snd_pcm_substream *substream)
551
{
552
struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream);
553
struct snd_pcm_runtime *runtime = substream->runtime;
554
555
runtime->hw = snd_sgio2audio_pcm_hw;
556
runtime->private_data = &chip->channel[2];
557
return 0;
558
}
559
560
/* PCM capture open callback */
561
static int snd_sgio2audio_capture_open(struct snd_pcm_substream *substream)
562
{
563
struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream);
564
struct snd_pcm_runtime *runtime = substream->runtime;
565
566
runtime->hw = snd_sgio2audio_pcm_hw;
567
runtime->private_data = &chip->channel[0];
568
return 0;
569
}
570
571
/* PCM close callback */
572
static int snd_sgio2audio_pcm_close(struct snd_pcm_substream *substream)
573
{
574
struct snd_pcm_runtime *runtime = substream->runtime;
575
576
runtime->private_data = NULL;
577
return 0;
578
}
579
580
/* prepare callback */
581
static int snd_sgio2audio_pcm_prepare(struct snd_pcm_substream *substream)
582
{
583
struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream);
584
struct snd_pcm_runtime *runtime = substream->runtime;
585
struct snd_sgio2audio_chan *chan = substream->runtime->private_data;
586
int ch = chan->idx;
587
unsigned long flags;
588
589
spin_lock_irqsave(&chip->channel[ch].lock, flags);
590
591
/* Setup the pseudo-dma transfer pointers. */
592
chip->channel[ch].pos = 0;
593
chip->channel[ch].size = 0;
594
chip->channel[ch].substream = substream;
595
596
/* set AD1843 format */
597
/* hardware format is always S16_LE */
598
switch (substream->stream) {
599
case SNDRV_PCM_STREAM_PLAYBACK:
600
ad1843_setup_dac(&chip->ad1843,
601
ch - 1,
602
runtime->rate,
603
SNDRV_PCM_FORMAT_S16_LE,
604
runtime->channels);
605
break;
606
case SNDRV_PCM_STREAM_CAPTURE:
607
ad1843_setup_adc(&chip->ad1843,
608
runtime->rate,
609
SNDRV_PCM_FORMAT_S16_LE,
610
runtime->channels);
611
break;
612
}
613
spin_unlock_irqrestore(&chip->channel[ch].lock, flags);
614
return 0;
615
}
616
617
/* trigger callback */
618
static int snd_sgio2audio_pcm_trigger(struct snd_pcm_substream *substream,
619
int cmd)
620
{
621
switch (cmd) {
622
case SNDRV_PCM_TRIGGER_START:
623
/* start the PCM engine */
624
snd_sgio2audio_dma_start(substream);
625
break;
626
case SNDRV_PCM_TRIGGER_STOP:
627
/* stop the PCM engine */
628
snd_sgio2audio_dma_stop(substream);
629
break;
630
default:
631
return -EINVAL;
632
}
633
return 0;
634
}
635
636
/* pointer callback */
637
static snd_pcm_uframes_t
638
snd_sgio2audio_pcm_pointer(struct snd_pcm_substream *substream)
639
{
640
struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream);
641
struct snd_sgio2audio_chan *chan = substream->runtime->private_data;
642
643
/* get the current hardware pointer */
644
return bytes_to_frames(substream->runtime,
645
chip->channel[chan->idx].pos);
646
}
647
648
/* operators */
649
static const struct snd_pcm_ops snd_sgio2audio_playback1_ops = {
650
.open = snd_sgio2audio_playback1_open,
651
.close = snd_sgio2audio_pcm_close,
652
.prepare = snd_sgio2audio_pcm_prepare,
653
.trigger = snd_sgio2audio_pcm_trigger,
654
.pointer = snd_sgio2audio_pcm_pointer,
655
};
656
657
static const struct snd_pcm_ops snd_sgio2audio_playback2_ops = {
658
.open = snd_sgio2audio_playback2_open,
659
.close = snd_sgio2audio_pcm_close,
660
.prepare = snd_sgio2audio_pcm_prepare,
661
.trigger = snd_sgio2audio_pcm_trigger,
662
.pointer = snd_sgio2audio_pcm_pointer,
663
};
664
665
static const struct snd_pcm_ops snd_sgio2audio_capture_ops = {
666
.open = snd_sgio2audio_capture_open,
667
.close = snd_sgio2audio_pcm_close,
668
.prepare = snd_sgio2audio_pcm_prepare,
669
.trigger = snd_sgio2audio_pcm_trigger,
670
.pointer = snd_sgio2audio_pcm_pointer,
671
};
672
673
/*
674
* definitions of capture are omitted here...
675
*/
676
677
/* create a pcm device */
678
static int snd_sgio2audio_new_pcm(struct snd_sgio2audio *chip)
679
{
680
struct snd_pcm *pcm;
681
int err;
682
683
/* create first pcm device with one outputs and one input */
684
err = snd_pcm_new(chip->card, "SGI O2 Audio", 0, 1, 1, &pcm);
685
if (err < 0)
686
return err;
687
688
pcm->private_data = chip;
689
strscpy(pcm->name, "SGI O2 DAC1");
690
691
/* set operators */
692
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
693
&snd_sgio2audio_playback1_ops);
694
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
695
&snd_sgio2audio_capture_ops);
696
snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0);
697
698
/* create second pcm device with one outputs and no input */
699
err = snd_pcm_new(chip->card, "SGI O2 Audio", 1, 1, 0, &pcm);
700
if (err < 0)
701
return err;
702
703
pcm->private_data = chip;
704
strscpy(pcm->name, "SGI O2 DAC2");
705
706
/* set operators */
707
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
708
&snd_sgio2audio_playback2_ops);
709
snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0);
710
711
return 0;
712
}
713
714
static struct {
715
int idx;
716
int irq;
717
irqreturn_t (*isr)(int, void *);
718
const char *desc;
719
} snd_sgio2_isr_table[] = {
720
{
721
.idx = 0,
722
.irq = MACEISA_AUDIO1_DMAT_IRQ,
723
.isr = snd_sgio2audio_dma_in_isr,
724
.desc = "Capture DMA Channel 0"
725
}, {
726
.idx = 0,
727
.irq = MACEISA_AUDIO1_OF_IRQ,
728
.isr = snd_sgio2audio_error_isr,
729
.desc = "Capture Overflow"
730
}, {
731
.idx = 1,
732
.irq = MACEISA_AUDIO2_DMAT_IRQ,
733
.isr = snd_sgio2audio_dma_out_isr,
734
.desc = "Playback DMA Channel 1"
735
}, {
736
.idx = 1,
737
.irq = MACEISA_AUDIO2_MERR_IRQ,
738
.isr = snd_sgio2audio_error_isr,
739
.desc = "Memory Error Channel 1"
740
}, {
741
.idx = 2,
742
.irq = MACEISA_AUDIO3_DMAT_IRQ,
743
.isr = snd_sgio2audio_dma_out_isr,
744
.desc = "Playback DMA Channel 2"
745
}, {
746
.idx = 2,
747
.irq = MACEISA_AUDIO3_MERR_IRQ,
748
.isr = snd_sgio2audio_error_isr,
749
.desc = "Memory Error Channel 2"
750
}
751
};
752
753
/* ALSA driver */
754
755
static int snd_sgio2audio_free(struct snd_sgio2audio *chip)
756
{
757
int i;
758
759
/* reset interface */
760
writeq(AUDIO_CONTROL_RESET, &mace->perif.audio.control);
761
udelay(1);
762
writeq(0, &mace->perif.audio.control);
763
764
/* release IRQ's */
765
for (i = 0; i < ARRAY_SIZE(snd_sgio2_isr_table); i++)
766
free_irq(snd_sgio2_isr_table[i].irq,
767
&chip->channel[snd_sgio2_isr_table[i].idx]);
768
769
dma_free_coherent(chip->card->dev, MACEISA_RINGBUFFERS_SIZE,
770
chip->ring_base, chip->ring_base_dma);
771
772
/* release card data */
773
kfree(chip);
774
return 0;
775
}
776
777
static int snd_sgio2audio_dev_free(struct snd_device *device)
778
{
779
struct snd_sgio2audio *chip = device->device_data;
780
781
return snd_sgio2audio_free(chip);
782
}
783
784
static const struct snd_device_ops ops = {
785
.dev_free = snd_sgio2audio_dev_free,
786
};
787
788
static int snd_sgio2audio_create(struct snd_card *card,
789
struct snd_sgio2audio **rchip)
790
{
791
struct snd_sgio2audio *chip;
792
int i, err;
793
794
*rchip = NULL;
795
796
/* check if a codec is attached to the interface */
797
/* (Audio or Audio/Video board present) */
798
if (!(readq(&mace->perif.audio.control) & AUDIO_CONTROL_CODEC_PRESENT))
799
return -ENOENT;
800
801
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
802
if (chip == NULL)
803
return -ENOMEM;
804
805
chip->card = card;
806
807
chip->ring_base = dma_alloc_coherent(card->dev,
808
MACEISA_RINGBUFFERS_SIZE,
809
&chip->ring_base_dma, GFP_KERNEL);
810
if (chip->ring_base == NULL) {
811
printk(KERN_ERR
812
"sgio2audio: could not allocate ring buffers\n");
813
kfree(chip);
814
return -ENOMEM;
815
}
816
817
spin_lock_init(&chip->ad1843_lock);
818
819
/* initialize channels */
820
for (i = 0; i < 3; i++) {
821
spin_lock_init(&chip->channel[i].lock);
822
chip->channel[i].idx = i;
823
}
824
825
/* allocate IRQs */
826
for (i = 0; i < ARRAY_SIZE(snd_sgio2_isr_table); i++) {
827
if (request_irq(snd_sgio2_isr_table[i].irq,
828
snd_sgio2_isr_table[i].isr,
829
0,
830
snd_sgio2_isr_table[i].desc,
831
&chip->channel[snd_sgio2_isr_table[i].idx])) {
832
snd_sgio2audio_free(chip);
833
printk(KERN_ERR "sgio2audio: cannot allocate irq %d\n",
834
snd_sgio2_isr_table[i].irq);
835
return -EBUSY;
836
}
837
}
838
839
/* reset the interface */
840
writeq(AUDIO_CONTROL_RESET, &mace->perif.audio.control);
841
udelay(1);
842
writeq(0, &mace->perif.audio.control);
843
msleep_interruptible(1); /* give time to recover */
844
845
/* set ring base */
846
writeq(chip->ring_base_dma, &mace->perif.ctrl.ringbase);
847
848
/* attach the AD1843 codec */
849
chip->ad1843.read = read_ad1843_reg;
850
chip->ad1843.write = write_ad1843_reg;
851
chip->ad1843.chip = chip;
852
853
/* initialize the AD1843 codec */
854
err = ad1843_init(&chip->ad1843);
855
if (err < 0) {
856
snd_sgio2audio_free(chip);
857
return err;
858
}
859
860
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
861
if (err < 0) {
862
snd_sgio2audio_free(chip);
863
return err;
864
}
865
*rchip = chip;
866
return 0;
867
}
868
869
static int snd_sgio2audio_probe(struct platform_device *pdev)
870
{
871
struct snd_card *card;
872
struct snd_sgio2audio *chip;
873
int err;
874
875
err = snd_card_new(&pdev->dev, index, id, THIS_MODULE, 0, &card);
876
if (err < 0)
877
return err;
878
879
err = snd_sgio2audio_create(card, &chip);
880
if (err < 0) {
881
snd_card_free(card);
882
return err;
883
}
884
885
err = snd_sgio2audio_new_pcm(chip);
886
if (err < 0) {
887
snd_card_free(card);
888
return err;
889
}
890
err = snd_sgio2audio_new_mixer(chip);
891
if (err < 0) {
892
snd_card_free(card);
893
return err;
894
}
895
896
strscpy(card->driver, "SGI O2 Audio");
897
strscpy(card->shortname, "SGI O2 Audio");
898
sprintf(card->longname, "%s irq %i-%i",
899
card->shortname,
900
MACEISA_AUDIO1_DMAT_IRQ,
901
MACEISA_AUDIO3_MERR_IRQ);
902
903
err = snd_card_register(card);
904
if (err < 0) {
905
snd_card_free(card);
906
return err;
907
}
908
platform_set_drvdata(pdev, card);
909
return 0;
910
}
911
912
static void snd_sgio2audio_remove(struct platform_device *pdev)
913
{
914
struct snd_card *card = platform_get_drvdata(pdev);
915
916
snd_card_free(card);
917
}
918
919
static struct platform_driver sgio2audio_driver = {
920
.probe = snd_sgio2audio_probe,
921
.remove = snd_sgio2audio_remove,
922
.driver = {
923
.name = "sgio2audio",
924
}
925
};
926
927
module_platform_driver(sgio2audio_driver);
928
929