Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/pci/au88x0/au88x0_pcm.c
26451 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
*/
4
5
/*
6
* Vortex PCM ALSA driver.
7
*
8
* Supports ADB and WT DMA. Unfortunately, WT channels do not run yet.
9
* It remains stuck,and DMA transfers do not happen.
10
*/
11
#include <sound/asoundef.h>
12
#include <linux/time.h>
13
#include <sound/core.h>
14
#include <sound/pcm.h>
15
#include <sound/pcm_params.h>
16
#include "au88x0.h"
17
18
#define VORTEX_PCM_TYPE(x) (x->name[40])
19
20
/* hardware definition */
21
static const struct snd_pcm_hardware snd_vortex_playback_hw_adb = {
22
.info =
23
(SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */
24
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED |
25
SNDRV_PCM_INFO_MMAP_VALID),
26
.formats =
27
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U8 |
28
SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW,
29
.rates = SNDRV_PCM_RATE_CONTINUOUS,
30
.rate_min = 5000,
31
.rate_max = 48000,
32
.channels_min = 1,
33
.channels_max = 2,
34
.buffer_bytes_max = 0x10000,
35
.period_bytes_min = 0x20,
36
.period_bytes_max = 0x1000,
37
.periods_min = 2,
38
.periods_max = 1024,
39
};
40
41
#ifndef CHIP_AU8820
42
static const struct snd_pcm_hardware snd_vortex_playback_hw_a3d = {
43
.info =
44
(SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */
45
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED |
46
SNDRV_PCM_INFO_MMAP_VALID),
47
.formats =
48
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U8 |
49
SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW,
50
.rates = SNDRV_PCM_RATE_CONTINUOUS,
51
.rate_min = 5000,
52
.rate_max = 48000,
53
.channels_min = 1,
54
.channels_max = 1,
55
.buffer_bytes_max = 0x10000,
56
.period_bytes_min = 0x100,
57
.period_bytes_max = 0x1000,
58
.periods_min = 2,
59
.periods_max = 64,
60
};
61
#endif
62
static const struct snd_pcm_hardware snd_vortex_playback_hw_spdif = {
63
.info =
64
(SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */
65
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED |
66
SNDRV_PCM_INFO_MMAP_VALID),
67
.formats =
68
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U8 |
69
SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE | SNDRV_PCM_FMTBIT_MU_LAW |
70
SNDRV_PCM_FMTBIT_A_LAW,
71
.rates =
72
SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
73
.rate_min = 32000,
74
.rate_max = 48000,
75
.channels_min = 1,
76
.channels_max = 2,
77
.buffer_bytes_max = 0x10000,
78
.period_bytes_min = 0x100,
79
.period_bytes_max = 0x1000,
80
.periods_min = 2,
81
.periods_max = 64,
82
};
83
84
#ifndef CHIP_AU8810
85
static const struct snd_pcm_hardware snd_vortex_playback_hw_wt = {
86
.info = (SNDRV_PCM_INFO_MMAP |
87
SNDRV_PCM_INFO_INTERLEAVED |
88
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID),
89
.formats = SNDRV_PCM_FMTBIT_S16_LE,
90
.rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_CONTINUOUS, // SNDRV_PCM_RATE_48000,
91
.rate_min = 8000,
92
.rate_max = 48000,
93
.channels_min = 1,
94
.channels_max = 2,
95
.buffer_bytes_max = 0x10000,
96
.period_bytes_min = 0x0400,
97
.period_bytes_max = 0x1000,
98
.periods_min = 2,
99
.periods_max = 64,
100
};
101
#endif
102
#ifdef CHIP_AU8830
103
static const unsigned int au8830_channels[3] = {
104
1, 2, 4,
105
};
106
107
static const struct snd_pcm_hw_constraint_list hw_constraints_au8830_channels = {
108
.count = ARRAY_SIZE(au8830_channels),
109
.list = au8830_channels,
110
.mask = 0,
111
};
112
#endif
113
114
static void vortex_notify_pcm_vol_change(struct snd_card *card,
115
struct snd_kcontrol *kctl, int activate)
116
{
117
if (activate)
118
kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
119
else
120
kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
121
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE |
122
SNDRV_CTL_EVENT_MASK_INFO, &(kctl->id));
123
}
124
125
/* open callback */
126
static int snd_vortex_pcm_open(struct snd_pcm_substream *substream)
127
{
128
vortex_t *vortex = snd_pcm_substream_chip(substream);
129
struct snd_pcm_runtime *runtime = substream->runtime;
130
int err;
131
132
/* Force equal size periods */
133
err = snd_pcm_hw_constraint_integer(runtime,
134
SNDRV_PCM_HW_PARAM_PERIODS);
135
if (err < 0)
136
return err;
137
/* Avoid PAGE_SIZE boundary to fall inside of a period. */
138
err = snd_pcm_hw_constraint_pow2(runtime, 0,
139
SNDRV_PCM_HW_PARAM_PERIOD_BYTES);
140
if (err < 0)
141
return err;
142
143
snd_pcm_hw_constraint_step(runtime, 0,
144
SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 64);
145
146
if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
147
#ifndef CHIP_AU8820
148
if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_A3D) {
149
runtime->hw = snd_vortex_playback_hw_a3d;
150
}
151
#endif
152
if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_SPDIF) {
153
runtime->hw = snd_vortex_playback_hw_spdif;
154
switch (vortex->spdif_sr) {
155
case 32000:
156
runtime->hw.rates = SNDRV_PCM_RATE_32000;
157
break;
158
case 44100:
159
runtime->hw.rates = SNDRV_PCM_RATE_44100;
160
break;
161
case 48000:
162
runtime->hw.rates = SNDRV_PCM_RATE_48000;
163
break;
164
}
165
}
166
if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB
167
|| VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_I2S)
168
runtime->hw = snd_vortex_playback_hw_adb;
169
#ifdef CHIP_AU8830
170
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
171
VORTEX_IS_QUAD(vortex) &&
172
VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
173
runtime->hw.channels_max = 4;
174
snd_pcm_hw_constraint_list(runtime, 0,
175
SNDRV_PCM_HW_PARAM_CHANNELS,
176
&hw_constraints_au8830_channels);
177
}
178
#endif
179
substream->runtime->private_data = NULL;
180
}
181
#ifndef CHIP_AU8810
182
else {
183
runtime->hw = snd_vortex_playback_hw_wt;
184
substream->runtime->private_data = NULL;
185
}
186
#endif
187
return 0;
188
}
189
190
/* close callback */
191
static int snd_vortex_pcm_close(struct snd_pcm_substream *substream)
192
{
193
//vortex_t *chip = snd_pcm_substream_chip(substream);
194
stream_t *stream = (stream_t *) substream->runtime->private_data;
195
196
// the hardware-specific codes will be here
197
if (stream != NULL) {
198
stream->substream = NULL;
199
stream->nr_ch = 0;
200
}
201
substream->runtime->private_data = NULL;
202
return 0;
203
}
204
205
/* hw_params callback */
206
static int
207
snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
208
struct snd_pcm_hw_params *hw_params)
209
{
210
vortex_t *chip = snd_pcm_substream_chip(substream);
211
stream_t *stream = (stream_t *) (substream->runtime->private_data);
212
213
/*
214
pr_info( "Vortex: periods %d, period_bytes %d, channels = %d\n", params_periods(hw_params),
215
params_period_bytes(hw_params), params_channels(hw_params));
216
*/
217
spin_lock_irq(&chip->lock);
218
// Make audio routes and config buffer DMA.
219
if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
220
int dma, type = VORTEX_PCM_TYPE(substream->pcm);
221
/* Dealloc any routes. */
222
if (stream != NULL)
223
vortex_adb_allocroute(chip, stream->dma,
224
stream->nr_ch, stream->dir,
225
stream->type,
226
substream->number);
227
/* Alloc routes. */
228
dma =
229
vortex_adb_allocroute(chip, -1,
230
params_channels(hw_params),
231
substream->stream, type,
232
substream->number);
233
if (dma < 0) {
234
spin_unlock_irq(&chip->lock);
235
return dma;
236
}
237
stream = substream->runtime->private_data = &chip->dma_adb[dma];
238
stream->substream = substream;
239
/* Setup Buffers. */
240
vortex_adbdma_setbuffers(chip, dma,
241
params_period_bytes(hw_params),
242
params_periods(hw_params));
243
if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
244
chip->pcm_vol[substream->number].active = 1;
245
vortex_notify_pcm_vol_change(chip->card,
246
chip->pcm_vol[substream->number].kctl, 1);
247
}
248
}
249
#ifndef CHIP_AU8810
250
else {
251
/* if (stream != NULL)
252
vortex_wt_allocroute(chip, substream->number, 0); */
253
vortex_wt_allocroute(chip, substream->number,
254
params_channels(hw_params));
255
stream = substream->runtime->private_data =
256
&chip->dma_wt[substream->number];
257
stream->dma = substream->number;
258
stream->substream = substream;
259
vortex_wtdma_setbuffers(chip, substream->number,
260
params_period_bytes(hw_params),
261
params_periods(hw_params));
262
}
263
#endif
264
spin_unlock_irq(&chip->lock);
265
return 0;
266
}
267
268
/* hw_free callback */
269
static int snd_vortex_pcm_hw_free(struct snd_pcm_substream *substream)
270
{
271
vortex_t *chip = snd_pcm_substream_chip(substream);
272
stream_t *stream = (stream_t *) (substream->runtime->private_data);
273
274
spin_lock_irq(&chip->lock);
275
// Delete audio routes.
276
if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
277
if (stream != NULL) {
278
if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
279
chip->pcm_vol[substream->number].active = 0;
280
vortex_notify_pcm_vol_change(chip->card,
281
chip->pcm_vol[substream->number].kctl,
282
0);
283
}
284
vortex_adb_allocroute(chip, stream->dma,
285
stream->nr_ch, stream->dir,
286
stream->type,
287
substream->number);
288
}
289
}
290
#ifndef CHIP_AU8810
291
else {
292
if (stream != NULL)
293
vortex_wt_allocroute(chip, stream->dma, 0);
294
}
295
#endif
296
substream->runtime->private_data = NULL;
297
spin_unlock_irq(&chip->lock);
298
299
return 0;
300
}
301
302
/* prepare callback */
303
static int snd_vortex_pcm_prepare(struct snd_pcm_substream *substream)
304
{
305
vortex_t *chip = snd_pcm_substream_chip(substream);
306
struct snd_pcm_runtime *runtime = substream->runtime;
307
stream_t *stream = (stream_t *) substream->runtime->private_data;
308
int dma = stream->dma, fmt, dir;
309
310
// set up the hardware with the current configuration.
311
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
312
dir = 1;
313
else
314
dir = 0;
315
fmt = vortex_alsafmt_aspfmt(runtime->format, chip);
316
spin_lock_irq(&chip->lock);
317
if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
318
vortex_adbdma_setmode(chip, dma, 1, dir, fmt,
319
runtime->channels == 1 ? 0 : 1, 0);
320
vortex_adbdma_setstartbuffer(chip, dma, 0);
321
if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_SPDIF)
322
vortex_adb_setsrc(chip, dma, runtime->rate, dir);
323
}
324
#ifndef CHIP_AU8810
325
else {
326
vortex_wtdma_setmode(chip, dma, 1, fmt, 0, 0);
327
// FIXME: Set rate (i guess using vortex_wt_writereg() somehow).
328
vortex_wtdma_setstartbuffer(chip, dma, 0);
329
}
330
#endif
331
spin_unlock_irq(&chip->lock);
332
return 0;
333
}
334
335
/* trigger callback */
336
static int snd_vortex_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
337
{
338
vortex_t *chip = snd_pcm_substream_chip(substream);
339
stream_t *stream = (stream_t *) substream->runtime->private_data;
340
int dma = stream->dma;
341
342
spin_lock(&chip->lock);
343
switch (cmd) {
344
case SNDRV_PCM_TRIGGER_START:
345
// do something to start the PCM engine
346
//printk(KERN_INFO "vortex: start %d\n", dma);
347
stream->fifo_enabled = 1;
348
if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
349
vortex_adbdma_resetup(chip, dma);
350
vortex_adbdma_startfifo(chip, dma);
351
}
352
#ifndef CHIP_AU8810
353
else {
354
dev_info(chip->card->dev, "wt start %d\n", dma);
355
vortex_wtdma_startfifo(chip, dma);
356
}
357
#endif
358
break;
359
case SNDRV_PCM_TRIGGER_STOP:
360
// do something to stop the PCM engine
361
//printk(KERN_INFO "vortex: stop %d\n", dma);
362
stream->fifo_enabled = 0;
363
if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
364
vortex_adbdma_stopfifo(chip, dma);
365
#ifndef CHIP_AU8810
366
else {
367
dev_info(chip->card->dev, "wt stop %d\n", dma);
368
vortex_wtdma_stopfifo(chip, dma);
369
}
370
#endif
371
break;
372
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
373
//printk(KERN_INFO "vortex: pause %d\n", dma);
374
if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
375
vortex_adbdma_pausefifo(chip, dma);
376
#ifndef CHIP_AU8810
377
else
378
vortex_wtdma_pausefifo(chip, dma);
379
#endif
380
break;
381
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
382
//printk(KERN_INFO "vortex: resume %d\n", dma);
383
if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
384
vortex_adbdma_resumefifo(chip, dma);
385
#ifndef CHIP_AU8810
386
else
387
vortex_wtdma_resumefifo(chip, dma);
388
#endif
389
break;
390
default:
391
spin_unlock(&chip->lock);
392
return -EINVAL;
393
}
394
spin_unlock(&chip->lock);
395
return 0;
396
}
397
398
/* pointer callback */
399
static snd_pcm_uframes_t snd_vortex_pcm_pointer(struct snd_pcm_substream *substream)
400
{
401
vortex_t *chip = snd_pcm_substream_chip(substream);
402
stream_t *stream = (stream_t *) substream->runtime->private_data;
403
int dma = stream->dma;
404
snd_pcm_uframes_t current_ptr = 0;
405
406
spin_lock(&chip->lock);
407
if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
408
current_ptr = vortex_adbdma_getlinearpos(chip, dma);
409
#ifndef CHIP_AU8810
410
else
411
current_ptr = vortex_wtdma_getlinearpos(chip, dma);
412
#endif
413
//printk(KERN_INFO "vortex: pointer = 0x%x\n", current_ptr);
414
spin_unlock(&chip->lock);
415
current_ptr = bytes_to_frames(substream->runtime, current_ptr);
416
if (current_ptr >= substream->runtime->buffer_size)
417
current_ptr = 0;
418
return current_ptr;
419
}
420
421
/* operators */
422
static const struct snd_pcm_ops snd_vortex_playback_ops = {
423
.open = snd_vortex_pcm_open,
424
.close = snd_vortex_pcm_close,
425
.hw_params = snd_vortex_pcm_hw_params,
426
.hw_free = snd_vortex_pcm_hw_free,
427
.prepare = snd_vortex_pcm_prepare,
428
.trigger = snd_vortex_pcm_trigger,
429
.pointer = snd_vortex_pcm_pointer,
430
};
431
432
/*
433
* definitions of capture are omitted here...
434
*/
435
436
static const char * const vortex_pcm_prettyname[VORTEX_PCM_LAST] = {
437
CARD_NAME " ADB",
438
CARD_NAME " SPDIF",
439
CARD_NAME " A3D",
440
CARD_NAME " WT",
441
CARD_NAME " I2S",
442
};
443
static const char * const vortex_pcm_name[VORTEX_PCM_LAST] = {
444
"adb",
445
"spdif",
446
"a3d",
447
"wt",
448
"i2s",
449
};
450
451
/* SPDIF kcontrol */
452
453
static int snd_vortex_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
454
{
455
uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
456
uinfo->count = 1;
457
return 0;
458
}
459
460
static int snd_vortex_spdif_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
461
{
462
ucontrol->value.iec958.status[0] = 0xff;
463
ucontrol->value.iec958.status[1] = 0xff;
464
ucontrol->value.iec958.status[2] = 0xff;
465
ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS;
466
return 0;
467
}
468
469
static int snd_vortex_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
470
{
471
vortex_t *vortex = snd_kcontrol_chip(kcontrol);
472
ucontrol->value.iec958.status[0] = 0x00;
473
ucontrol->value.iec958.status[1] = IEC958_AES1_CON_ORIGINAL|IEC958_AES1_CON_DIGDIGCONV_ID;
474
ucontrol->value.iec958.status[2] = 0x00;
475
switch (vortex->spdif_sr) {
476
case 32000: ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_32000; break;
477
case 44100: ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_44100; break;
478
case 48000: ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_48000; break;
479
}
480
return 0;
481
}
482
483
static int snd_vortex_spdif_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
484
{
485
vortex_t *vortex = snd_kcontrol_chip(kcontrol);
486
int spdif_sr = 48000;
487
switch (ucontrol->value.iec958.status[3] & IEC958_AES3_CON_FS) {
488
case IEC958_AES3_CON_FS_32000: spdif_sr = 32000; break;
489
case IEC958_AES3_CON_FS_44100: spdif_sr = 44100; break;
490
case IEC958_AES3_CON_FS_48000: spdif_sr = 48000; break;
491
}
492
if (spdif_sr == vortex->spdif_sr)
493
return 0;
494
vortex->spdif_sr = spdif_sr;
495
vortex_spdif_init(vortex, vortex->spdif_sr, 1);
496
return 1;
497
}
498
499
/* spdif controls */
500
static const struct snd_kcontrol_new snd_vortex_mixer_spdif[] = {
501
{
502
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
503
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
504
.info = snd_vortex_spdif_info,
505
.get = snd_vortex_spdif_get,
506
.put = snd_vortex_spdif_put,
507
},
508
{
509
.access = SNDRV_CTL_ELEM_ACCESS_READ,
510
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
511
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
512
.info = snd_vortex_spdif_info,
513
.get = snd_vortex_spdif_mask_get
514
},
515
};
516
517
/* subdevice PCM Volume control */
518
519
static int snd_vortex_pcm_vol_info(struct snd_kcontrol *kcontrol,
520
struct snd_ctl_elem_info *uinfo)
521
{
522
vortex_t *vortex = snd_kcontrol_chip(kcontrol);
523
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
524
uinfo->count = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
525
uinfo->value.integer.min = -128;
526
uinfo->value.integer.max = 32;
527
return 0;
528
}
529
530
static int snd_vortex_pcm_vol_get(struct snd_kcontrol *kcontrol,
531
struct snd_ctl_elem_value *ucontrol)
532
{
533
int i;
534
vortex_t *vortex = snd_kcontrol_chip(kcontrol);
535
int subdev = kcontrol->id.subdevice;
536
struct pcm_vol *p = &vortex->pcm_vol[subdev];
537
int max_chn = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
538
for (i = 0; i < max_chn; i++)
539
ucontrol->value.integer.value[i] = p->vol[i];
540
return 0;
541
}
542
543
static int snd_vortex_pcm_vol_put(struct snd_kcontrol *kcontrol,
544
struct snd_ctl_elem_value *ucontrol)
545
{
546
int i;
547
int changed = 0;
548
int mixin;
549
unsigned char vol;
550
vortex_t *vortex = snd_kcontrol_chip(kcontrol);
551
int subdev = kcontrol->id.subdevice;
552
struct pcm_vol *p = &vortex->pcm_vol[subdev];
553
int max_chn = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
554
for (i = 0; i < max_chn; i++) {
555
if (p->vol[i] != ucontrol->value.integer.value[i]) {
556
p->vol[i] = ucontrol->value.integer.value[i];
557
if (p->active) {
558
switch (vortex->dma_adb[p->dma].nr_ch) {
559
case 1:
560
mixin = p->mixin[0];
561
break;
562
case 2:
563
default:
564
mixin = p->mixin[(i < 2) ? i : (i - 2)];
565
break;
566
case 4:
567
mixin = p->mixin[i];
568
break;
569
}
570
vol = p->vol[i];
571
vortex_mix_setinputvolumebyte(vortex,
572
vortex->mixplayb[i], mixin, vol);
573
}
574
changed = 1;
575
}
576
}
577
return changed;
578
}
579
580
static const DECLARE_TLV_DB_MINMAX(vortex_pcm_vol_db_scale, -9600, 2400);
581
582
static const struct snd_kcontrol_new snd_vortex_pcm_vol = {
583
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
584
.name = "PCM Playback Volume",
585
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
586
SNDRV_CTL_ELEM_ACCESS_TLV_READ |
587
SNDRV_CTL_ELEM_ACCESS_INACTIVE,
588
.info = snd_vortex_pcm_vol_info,
589
.get = snd_vortex_pcm_vol_get,
590
.put = snd_vortex_pcm_vol_put,
591
.tlv = { .p = vortex_pcm_vol_db_scale },
592
};
593
594
/* create a pcm device */
595
static int snd_vortex_new_pcm(vortex_t *chip, int idx, int nr)
596
{
597
struct snd_pcm *pcm;
598
struct snd_kcontrol *kctl;
599
int i;
600
int err, nr_capt;
601
602
if (!chip || idx < 0 || idx >= VORTEX_PCM_LAST)
603
return -ENODEV;
604
605
/* idx indicates which kind of PCM device. ADB, SPDIF, I2S and A3D share the
606
* same dma engine. WT uses it own separate dma engine which can't capture. */
607
if (idx == VORTEX_PCM_ADB)
608
nr_capt = nr;
609
else
610
nr_capt = 0;
611
err = snd_pcm_new(chip->card, vortex_pcm_prettyname[idx], idx, nr,
612
nr_capt, &pcm);
613
if (err < 0)
614
return err;
615
snprintf(pcm->name, sizeof(pcm->name),
616
"%s %s", CARD_NAME_SHORT, vortex_pcm_name[idx]);
617
chip->pcm[idx] = pcm;
618
// This is an evil hack, but it saves a lot of duplicated code.
619
VORTEX_PCM_TYPE(pcm) = idx;
620
pcm->private_data = chip;
621
/* set operators */
622
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
623
&snd_vortex_playback_ops);
624
if (idx == VORTEX_PCM_ADB)
625
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
626
&snd_vortex_playback_ops);
627
628
/* pre-allocation of Scatter-Gather buffers */
629
630
snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
631
&chip->pci_dev->dev, 0x10000, 0x10000);
632
633
switch (VORTEX_PCM_TYPE(pcm)) {
634
case VORTEX_PCM_ADB:
635
err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
636
snd_pcm_std_chmaps,
637
VORTEX_IS_QUAD(chip) ? 4 : 2,
638
0, NULL);
639
if (err < 0)
640
return err;
641
err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_CAPTURE,
642
snd_pcm_std_chmaps, 2, 0, NULL);
643
if (err < 0)
644
return err;
645
break;
646
#ifdef CHIP_AU8830
647
case VORTEX_PCM_A3D:
648
err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
649
snd_pcm_std_chmaps, 1, 0, NULL);
650
if (err < 0)
651
return err;
652
break;
653
#endif
654
}
655
656
if (VORTEX_PCM_TYPE(pcm) == VORTEX_PCM_SPDIF) {
657
for (i = 0; i < ARRAY_SIZE(snd_vortex_mixer_spdif); i++) {
658
kctl = snd_ctl_new1(&snd_vortex_mixer_spdif[i], chip);
659
if (!kctl)
660
return -ENOMEM;
661
err = snd_ctl_add(chip->card, kctl);
662
if (err < 0)
663
return err;
664
}
665
}
666
if (VORTEX_PCM_TYPE(pcm) == VORTEX_PCM_ADB) {
667
for (i = 0; i < NR_PCM; i++) {
668
chip->pcm_vol[i].active = 0;
669
chip->pcm_vol[i].dma = -1;
670
kctl = snd_ctl_new1(&snd_vortex_pcm_vol, chip);
671
if (!kctl)
672
return -ENOMEM;
673
chip->pcm_vol[i].kctl = kctl;
674
kctl->id.device = 0;
675
kctl->id.subdevice = i;
676
err = snd_ctl_add(chip->card, kctl);
677
if (err < 0)
678
return err;
679
}
680
}
681
return 0;
682
}
683
684