Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/pci/cs46xx/cs46xx_lib.c
29266 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* Copyright (c) by Jaroslav Kysela <[email protected]>
4
* Abramo Bagnara <[email protected]>
5
* Cirrus Logic, Inc.
6
* Routines for control of Cirrus Logic CS461x chips
7
*
8
* KNOWN BUGS:
9
* - Sometimes the SPDIF input DSP tasks get's unsynchronized
10
* and the SPDIF get somewhat "distorcionated", or/and left right channel
11
* are swapped. To get around this problem when it happens, mute and unmute
12
* the SPDIF input mixer control.
13
* - On the Hercules Game Theater XP the amplifier are sometimes turned
14
* off on inadecuate moments which causes distorcions on sound.
15
*
16
* TODO:
17
* - Secondary CODEC on some soundcards
18
* - SPDIF input support for other sample rates then 48khz
19
* - Posibility to mix the SPDIF output with analog sources.
20
* - PCM channels for Center and LFE on secondary codec
21
*
22
* NOTE: with CONFIG_SND_CS46XX_NEW_DSP unset uses old DSP image (which
23
* is default configuration), no SPDIF, no secondary codec, no
24
* multi channel PCM. But known to work.
25
*
26
* FINALLY: A credit to the developers Tom and Jordan
27
* at Cirrus for have helping me out with the DSP, however we
28
* still don't have sufficient documentation and technical
29
* references to be able to implement all fancy feutures
30
* supported by the cs46xx DSP's.
31
* Benny <[email protected]>
32
*/
33
34
#include <linux/delay.h>
35
#include <linux/pci.h>
36
#include <linux/pm.h>
37
#include <linux/init.h>
38
#include <linux/interrupt.h>
39
#include <linux/slab.h>
40
#include <linux/gameport.h>
41
#include <linux/mutex.h>
42
#include <linux/export.h>
43
#include <linux/module.h>
44
#include <linux/firmware.h>
45
#include <linux/vmalloc.h>
46
#include <linux/io.h>
47
48
#include <sound/core.h>
49
#include <sound/control.h>
50
#include <sound/info.h>
51
#include <sound/pcm.h>
52
#include <sound/pcm_params.h>
53
#include "cs46xx.h"
54
55
#include "cs46xx_lib.h"
56
#include "dsp_spos.h"
57
58
static void amp_voyetra(struct snd_cs46xx *chip, int change);
59
60
#ifdef CONFIG_SND_CS46XX_NEW_DSP
61
static const struct snd_pcm_ops snd_cs46xx_playback_rear_ops;
62
static const struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops;
63
static const struct snd_pcm_ops snd_cs46xx_playback_clfe_ops;
64
static const struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops;
65
static const struct snd_pcm_ops snd_cs46xx_playback_iec958_ops;
66
static const struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops;
67
#endif
68
69
static const struct snd_pcm_ops snd_cs46xx_playback_ops;
70
static const struct snd_pcm_ops snd_cs46xx_playback_indirect_ops;
71
static const struct snd_pcm_ops snd_cs46xx_capture_ops;
72
static const struct snd_pcm_ops snd_cs46xx_capture_indirect_ops;
73
74
static unsigned short snd_cs46xx_codec_read(struct snd_cs46xx *chip,
75
unsigned short reg,
76
int codec_index)
77
{
78
int count;
79
unsigned short result,tmp;
80
u32 offset = 0;
81
82
if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX &&
83
codec_index != CS46XX_SECONDARY_CODEC_INDEX))
84
return 0xffff;
85
86
chip->active_ctrl(chip, 1);
87
88
if (codec_index == CS46XX_SECONDARY_CODEC_INDEX)
89
offset = CS46XX_SECONDARY_CODEC_OFFSET;
90
91
/*
92
* 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
93
* 2. Write ACCDA = Command Data Register = 470h for data to write to AC97
94
* 3. Write ACCTL = Control Register = 460h for initiating the write7---55
95
* 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 17h
96
* 5. if DCV not cleared, break and return error
97
* 6. Read ACSTS = Status Register = 464h, check VSTS bit
98
*/
99
100
snd_cs46xx_peekBA0(chip, BA0_ACSDA + offset);
101
102
tmp = snd_cs46xx_peekBA0(chip, BA0_ACCTL);
103
if ((tmp & ACCTL_VFRM) == 0) {
104
dev_warn(chip->card->dev, "ACCTL_VFRM not set 0x%x\n", tmp);
105
snd_cs46xx_pokeBA0(chip, BA0_ACCTL, (tmp & (~ACCTL_ESYN)) | ACCTL_VFRM );
106
msleep(50);
107
tmp = snd_cs46xx_peekBA0(chip, BA0_ACCTL + offset);
108
snd_cs46xx_pokeBA0(chip, BA0_ACCTL, tmp | ACCTL_ESYN | ACCTL_VFRM );
109
110
}
111
112
/*
113
* Setup the AC97 control registers on the CS461x to send the
114
* appropriate command to the AC97 to perform the read.
115
* ACCAD = Command Address Register = 46Ch
116
* ACCDA = Command Data Register = 470h
117
* ACCTL = Control Register = 460h
118
* set DCV - will clear when process completed
119
* set CRW - Read command
120
* set VFRM - valid frame enabled
121
* set ESYN - ASYNC generation enabled
122
* set RSTN - ARST# inactive, AC97 codec not reset
123
*/
124
125
snd_cs46xx_pokeBA0(chip, BA0_ACCAD, reg);
126
snd_cs46xx_pokeBA0(chip, BA0_ACCDA, 0);
127
if (codec_index == CS46XX_PRIMARY_CODEC_INDEX) {
128
snd_cs46xx_pokeBA0(chip, BA0_ACCTL,/* clear ACCTL_DCV */ ACCTL_CRW |
129
ACCTL_VFRM | ACCTL_ESYN |
130
ACCTL_RSTN);
131
snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_CRW |
132
ACCTL_VFRM | ACCTL_ESYN |
133
ACCTL_RSTN);
134
} else {
135
snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_TC |
136
ACCTL_CRW | ACCTL_VFRM | ACCTL_ESYN |
137
ACCTL_RSTN);
138
}
139
140
/*
141
* Wait for the read to occur.
142
*/
143
for (count = 0; count < 1000; count++) {
144
/*
145
* First, we want to wait for a short time.
146
*/
147
udelay(10);
148
/*
149
* Now, check to see if the read has completed.
150
* ACCTL = 460h, DCV should be reset by now and 460h = 17h
151
*/
152
if (!(snd_cs46xx_peekBA0(chip, BA0_ACCTL) & ACCTL_DCV))
153
goto ok1;
154
}
155
156
dev_err(chip->card->dev,
157
"AC'97 read problem (ACCTL_DCV), reg = 0x%x\n", reg);
158
result = 0xffff;
159
goto end;
160
161
ok1:
162
/*
163
* Wait for the valid status bit to go active.
164
*/
165
for (count = 0; count < 100; count++) {
166
/*
167
* Read the AC97 status register.
168
* ACSTS = Status Register = 464h
169
* VSTS - Valid Status
170
*/
171
if (snd_cs46xx_peekBA0(chip, BA0_ACSTS + offset) & ACSTS_VSTS)
172
goto ok2;
173
udelay(10);
174
}
175
176
dev_err(chip->card->dev,
177
"AC'97 read problem (ACSTS_VSTS), codec_index %d, reg = 0x%x\n",
178
codec_index, reg);
179
result = 0xffff;
180
goto end;
181
182
ok2:
183
/*
184
* Read the data returned from the AC97 register.
185
* ACSDA = Status Data Register = 474h
186
*/
187
#if 0
188
dev_dbg(chip->card->dev,
189
"e) reg = 0x%x, val = 0x%x, BA0_ACCAD = 0x%x\n", reg,
190
snd_cs46xx_peekBA0(chip, BA0_ACSDA),
191
snd_cs46xx_peekBA0(chip, BA0_ACCAD));
192
#endif
193
194
//snd_cs46xx_peekBA0(chip, BA0_ACCAD);
195
result = snd_cs46xx_peekBA0(chip, BA0_ACSDA + offset);
196
end:
197
chip->active_ctrl(chip, -1);
198
return result;
199
}
200
201
static unsigned short snd_cs46xx_ac97_read(struct snd_ac97 * ac97,
202
unsigned short reg)
203
{
204
struct snd_cs46xx *chip = ac97->private_data;
205
unsigned short val;
206
int codec_index = ac97->num;
207
208
if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX &&
209
codec_index != CS46XX_SECONDARY_CODEC_INDEX))
210
return 0xffff;
211
212
val = snd_cs46xx_codec_read(chip, reg, codec_index);
213
214
return val;
215
}
216
217
218
static void snd_cs46xx_codec_write(struct snd_cs46xx *chip,
219
unsigned short reg,
220
unsigned short val,
221
int codec_index)
222
{
223
int count;
224
225
if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX &&
226
codec_index != CS46XX_SECONDARY_CODEC_INDEX))
227
return;
228
229
chip->active_ctrl(chip, 1);
230
231
/*
232
* 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
233
* 2. Write ACCDA = Command Data Register = 470h for data to write to AC97
234
* 3. Write ACCTL = Control Register = 460h for initiating the write
235
* 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 07h
236
* 5. if DCV not cleared, break and return error
237
*/
238
239
/*
240
* Setup the AC97 control registers on the CS461x to send the
241
* appropriate command to the AC97 to perform the read.
242
* ACCAD = Command Address Register = 46Ch
243
* ACCDA = Command Data Register = 470h
244
* ACCTL = Control Register = 460h
245
* set DCV - will clear when process completed
246
* reset CRW - Write command
247
* set VFRM - valid frame enabled
248
* set ESYN - ASYNC generation enabled
249
* set RSTN - ARST# inactive, AC97 codec not reset
250
*/
251
snd_cs46xx_pokeBA0(chip, BA0_ACCAD , reg);
252
snd_cs46xx_pokeBA0(chip, BA0_ACCDA , val);
253
snd_cs46xx_peekBA0(chip, BA0_ACCTL);
254
255
if (codec_index == CS46XX_PRIMARY_CODEC_INDEX) {
256
snd_cs46xx_pokeBA0(chip, BA0_ACCTL, /* clear ACCTL_DCV */ ACCTL_VFRM |
257
ACCTL_ESYN | ACCTL_RSTN);
258
snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_VFRM |
259
ACCTL_ESYN | ACCTL_RSTN);
260
} else {
261
snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_TC |
262
ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN);
263
}
264
265
for (count = 0; count < 4000; count++) {
266
/*
267
* First, we want to wait for a short time.
268
*/
269
udelay(10);
270
/*
271
* Now, check to see if the write has completed.
272
* ACCTL = 460h, DCV should be reset by now and 460h = 07h
273
*/
274
if (!(snd_cs46xx_peekBA0(chip, BA0_ACCTL) & ACCTL_DCV)) {
275
goto end;
276
}
277
}
278
dev_err(chip->card->dev,
279
"AC'97 write problem, codec_index = %d, reg = 0x%x, val = 0x%x\n",
280
codec_index, reg, val);
281
end:
282
chip->active_ctrl(chip, -1);
283
}
284
285
static void snd_cs46xx_ac97_write(struct snd_ac97 *ac97,
286
unsigned short reg,
287
unsigned short val)
288
{
289
struct snd_cs46xx *chip = ac97->private_data;
290
int codec_index = ac97->num;
291
292
if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX &&
293
codec_index != CS46XX_SECONDARY_CODEC_INDEX))
294
return;
295
296
snd_cs46xx_codec_write(chip, reg, val, codec_index);
297
}
298
299
300
/*
301
* Chip initialization
302
*/
303
304
int snd_cs46xx_download(struct snd_cs46xx *chip,
305
u32 *src,
306
unsigned long offset,
307
unsigned long len)
308
{
309
void __iomem *dst;
310
unsigned int bank = offset >> 16;
311
offset = offset & 0xffff;
312
313
if (snd_BUG_ON((offset & 3) || (len & 3)))
314
return -EINVAL;
315
dst = chip->region.idx[bank+1].remap_addr + offset;
316
len /= sizeof(u32);
317
318
/* writel already converts 32-bit value to right endianess */
319
while (len-- > 0) {
320
writel(*src++, dst);
321
dst += sizeof(u32);
322
}
323
return 0;
324
}
325
326
static inline void memcpy_le32(void *dst, const void *src, unsigned int len)
327
{
328
#ifdef __LITTLE_ENDIAN
329
memcpy(dst, src, len);
330
#else
331
u32 *_dst = dst;
332
const __le32 *_src = src;
333
len /= 4;
334
while (len-- > 0)
335
*_dst++ = le32_to_cpu(*_src++);
336
#endif
337
}
338
339
#ifdef CONFIG_SND_CS46XX_NEW_DSP
340
341
static const char *module_names[CS46XX_DSP_MODULES] = {
342
"cwc4630", "cwcasync", "cwcsnoop", "cwcbinhack", "cwcdma"
343
};
344
345
MODULE_FIRMWARE("cs46xx/cwc4630");
346
MODULE_FIRMWARE("cs46xx/cwcasync");
347
MODULE_FIRMWARE("cs46xx/cwcsnoop");
348
MODULE_FIRMWARE("cs46xx/cwcbinhack");
349
MODULE_FIRMWARE("cs46xx/cwcdma");
350
351
static void free_module_desc(struct dsp_module_desc *module)
352
{
353
if (!module)
354
return;
355
kfree(module->module_name);
356
kfree(module->symbol_table.symbols);
357
if (module->segments) {
358
int i;
359
for (i = 0; i < module->nsegments; i++)
360
kfree(module->segments[i].data);
361
kfree(module->segments);
362
}
363
kfree(module);
364
}
365
366
/* firmware binary format:
367
* le32 nsymbols;
368
* struct {
369
* le32 address;
370
* char symbol_name[DSP_MAX_SYMBOL_NAME];
371
* le32 symbol_type;
372
* } symbols[nsymbols];
373
* le32 nsegments;
374
* struct {
375
* le32 segment_type;
376
* le32 offset;
377
* le32 size;
378
* le32 data[size];
379
* } segments[nsegments];
380
*/
381
382
static int load_firmware(struct snd_cs46xx *chip,
383
struct dsp_module_desc **module_ret,
384
const char *fw_name)
385
{
386
int i, err;
387
unsigned int nums, fwlen, fwsize;
388
const __le32 *fwdat;
389
struct dsp_module_desc *module = NULL;
390
const struct firmware *fw;
391
char fw_path[32];
392
393
sprintf(fw_path, "cs46xx/%s", fw_name);
394
err = request_firmware(&fw, fw_path, &chip->pci->dev);
395
if (err < 0)
396
return err;
397
fwsize = fw->size / 4;
398
if (fwsize < 2) {
399
err = -EINVAL;
400
goto error;
401
}
402
403
err = -ENOMEM;
404
module = kzalloc(sizeof(*module), GFP_KERNEL);
405
if (!module)
406
goto error;
407
module->module_name = kstrdup(fw_name, GFP_KERNEL);
408
if (!module->module_name)
409
goto error;
410
411
fwlen = 0;
412
fwdat = (const __le32 *)fw->data;
413
nums = module->symbol_table.nsymbols = le32_to_cpu(fwdat[fwlen++]);
414
if (nums >= 40)
415
goto error_inval;
416
module->symbol_table.symbols =
417
kcalloc(nums, sizeof(struct dsp_symbol_entry), GFP_KERNEL);
418
if (!module->symbol_table.symbols)
419
goto error;
420
for (i = 0; i < nums; i++) {
421
struct dsp_symbol_entry *entry =
422
&module->symbol_table.symbols[i];
423
if (fwlen + 2 + DSP_MAX_SYMBOL_NAME / 4 > fwsize)
424
goto error_inval;
425
entry->address = le32_to_cpu(fwdat[fwlen++]);
426
memcpy(entry->symbol_name, &fwdat[fwlen], DSP_MAX_SYMBOL_NAME - 1);
427
fwlen += DSP_MAX_SYMBOL_NAME / 4;
428
entry->symbol_type = le32_to_cpu(fwdat[fwlen++]);
429
}
430
431
if (fwlen >= fwsize)
432
goto error_inval;
433
nums = module->nsegments = le32_to_cpu(fwdat[fwlen++]);
434
if (nums > 10)
435
goto error_inval;
436
module->segments =
437
kcalloc(nums, sizeof(struct dsp_segment_desc), GFP_KERNEL);
438
if (!module->segments)
439
goto error;
440
for (i = 0; i < nums; i++) {
441
struct dsp_segment_desc *entry = &module->segments[i];
442
if (fwlen + 3 > fwsize)
443
goto error_inval;
444
entry->segment_type = le32_to_cpu(fwdat[fwlen++]);
445
entry->offset = le32_to_cpu(fwdat[fwlen++]);
446
entry->size = le32_to_cpu(fwdat[fwlen++]);
447
if (fwlen + entry->size > fwsize)
448
goto error_inval;
449
entry->data = kmalloc_array(entry->size, 4, GFP_KERNEL);
450
if (!entry->data)
451
goto error;
452
memcpy_le32(entry->data, &fwdat[fwlen], entry->size * 4);
453
fwlen += entry->size;
454
}
455
456
*module_ret = module;
457
release_firmware(fw);
458
return 0;
459
460
error_inval:
461
err = -EINVAL;
462
error:
463
free_module_desc(module);
464
release_firmware(fw);
465
return err;
466
}
467
468
int snd_cs46xx_clear_BA1(struct snd_cs46xx *chip,
469
unsigned long offset,
470
unsigned long len)
471
{
472
void __iomem *dst;
473
unsigned int bank = offset >> 16;
474
offset = offset & 0xffff;
475
476
if (snd_BUG_ON((offset & 3) || (len & 3)))
477
return -EINVAL;
478
dst = chip->region.idx[bank+1].remap_addr + offset;
479
len /= sizeof(u32);
480
481
/* writel already converts 32-bit value to right endianess */
482
while (len-- > 0) {
483
writel(0, dst);
484
dst += sizeof(u32);
485
}
486
return 0;
487
}
488
489
#else /* old DSP image */
490
491
struct ba1_struct {
492
struct {
493
u32 offset;
494
u32 size;
495
} memory[BA1_MEMORY_COUNT];
496
u32 map[BA1_DWORD_SIZE];
497
};
498
499
MODULE_FIRMWARE("cs46xx/ba1");
500
501
static int load_firmware(struct snd_cs46xx *chip)
502
{
503
const struct firmware *fw;
504
int i, size, err;
505
506
err = request_firmware(&fw, "cs46xx/ba1", &chip->pci->dev);
507
if (err < 0)
508
return err;
509
if (fw->size != sizeof(*chip->ba1)) {
510
err = -EINVAL;
511
goto error;
512
}
513
514
chip->ba1 = vmalloc(sizeof(*chip->ba1));
515
if (!chip->ba1) {
516
err = -ENOMEM;
517
goto error;
518
}
519
520
memcpy_le32(chip->ba1, fw->data, sizeof(*chip->ba1));
521
522
/* sanity check */
523
size = 0;
524
for (i = 0; i < BA1_MEMORY_COUNT; i++)
525
size += chip->ba1->memory[i].size;
526
if (size > BA1_DWORD_SIZE * 4)
527
err = -EINVAL;
528
529
error:
530
release_firmware(fw);
531
return err;
532
}
533
534
static __maybe_unused int snd_cs46xx_download_image(struct snd_cs46xx *chip)
535
{
536
int idx, err;
537
unsigned int offset = 0;
538
struct ba1_struct *ba1 = chip->ba1;
539
540
for (idx = 0; idx < BA1_MEMORY_COUNT; idx++) {
541
err = snd_cs46xx_download(chip,
542
&ba1->map[offset],
543
ba1->memory[idx].offset,
544
ba1->memory[idx].size);
545
if (err < 0)
546
return err;
547
offset += ba1->memory[idx].size >> 2;
548
}
549
return 0;
550
}
551
#endif /* CONFIG_SND_CS46XX_NEW_DSP */
552
553
/*
554
* Chip reset
555
*/
556
557
static void snd_cs46xx_reset(struct snd_cs46xx *chip)
558
{
559
int idx;
560
561
/*
562
* Write the reset bit of the SP control register.
563
*/
564
snd_cs46xx_poke(chip, BA1_SPCR, SPCR_RSTSP);
565
566
/*
567
* Write the control register.
568
*/
569
snd_cs46xx_poke(chip, BA1_SPCR, SPCR_DRQEN);
570
571
/*
572
* Clear the trap registers.
573
*/
574
for (idx = 0; idx < 8; idx++) {
575
snd_cs46xx_poke(chip, BA1_DREG, DREG_REGID_TRAP_SELECT + idx);
576
snd_cs46xx_poke(chip, BA1_TWPR, 0xFFFF);
577
}
578
snd_cs46xx_poke(chip, BA1_DREG, 0);
579
580
/*
581
* Set the frame timer to reflect the number of cycles per frame.
582
*/
583
snd_cs46xx_poke(chip, BA1_FRMT, 0xadf);
584
}
585
586
static int cs46xx_wait_for_fifo(struct snd_cs46xx * chip,int retry_timeout)
587
{
588
u32 i, status = 0;
589
/*
590
* Make sure the previous FIFO write operation has completed.
591
*/
592
for(i = 0; i < 50; i++){
593
status = snd_cs46xx_peekBA0(chip, BA0_SERBST);
594
595
if( !(status & SERBST_WBSY) )
596
break;
597
598
mdelay(retry_timeout);
599
}
600
601
if(status & SERBST_WBSY) {
602
dev_err(chip->card->dev,
603
"failure waiting for FIFO command to complete\n");
604
return -EINVAL;
605
}
606
607
return 0;
608
}
609
610
static void snd_cs46xx_clear_serial_FIFOs(struct snd_cs46xx *chip)
611
{
612
int idx, powerdown = 0;
613
unsigned int tmp;
614
615
/*
616
* See if the devices are powered down. If so, we must power them up first
617
* or they will not respond.
618
*/
619
tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1);
620
if (!(tmp & CLKCR1_SWCE)) {
621
snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp | CLKCR1_SWCE);
622
powerdown = 1;
623
}
624
625
/*
626
* We want to clear out the serial port FIFOs so we don't end up playing
627
* whatever random garbage happens to be in them. We fill the sample FIFOS
628
* with zero (silence).
629
*/
630
snd_cs46xx_pokeBA0(chip, BA0_SERBWP, 0);
631
632
/*
633
* Fill all 256 sample FIFO locations.
634
*/
635
for (idx = 0; idx < 0xFF; idx++) {
636
/*
637
* Make sure the previous FIFO write operation has completed.
638
*/
639
if (cs46xx_wait_for_fifo(chip,1)) {
640
dev_dbg(chip->card->dev,
641
"failed waiting for FIFO at addr (%02X)\n",
642
idx);
643
644
if (powerdown)
645
snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp);
646
647
break;
648
}
649
/*
650
* Write the serial port FIFO index.
651
*/
652
snd_cs46xx_pokeBA0(chip, BA0_SERBAD, idx);
653
/*
654
* Tell the serial port to load the new value into the FIFO location.
655
*/
656
snd_cs46xx_pokeBA0(chip, BA0_SERBCM, SERBCM_WRC);
657
}
658
/*
659
* Now, if we powered up the devices, then power them back down again.
660
* This is kinda ugly, but should never happen.
661
*/
662
if (powerdown)
663
snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp);
664
}
665
666
static void snd_cs46xx_proc_start(struct snd_cs46xx *chip)
667
{
668
int cnt;
669
670
/*
671
* Set the frame timer to reflect the number of cycles per frame.
672
*/
673
snd_cs46xx_poke(chip, BA1_FRMT, 0xadf);
674
/*
675
* Turn on the run, run at frame, and DMA enable bits in the local copy of
676
* the SP control register.
677
*/
678
snd_cs46xx_poke(chip, BA1_SPCR, SPCR_RUN | SPCR_RUNFR | SPCR_DRQEN);
679
/*
680
* Wait until the run at frame bit resets itself in the SP control
681
* register.
682
*/
683
for (cnt = 0; cnt < 25; cnt++) {
684
udelay(50);
685
if (!(snd_cs46xx_peek(chip, BA1_SPCR) & SPCR_RUNFR))
686
break;
687
}
688
689
if (snd_cs46xx_peek(chip, BA1_SPCR) & SPCR_RUNFR)
690
dev_err(chip->card->dev, "SPCR_RUNFR never reset\n");
691
}
692
693
static void snd_cs46xx_proc_stop(struct snd_cs46xx *chip)
694
{
695
/*
696
* Turn off the run, run at frame, and DMA enable bits in the local copy of
697
* the SP control register.
698
*/
699
snd_cs46xx_poke(chip, BA1_SPCR, 0);
700
}
701
702
/*
703
* Sample rate routines
704
*/
705
706
#define GOF_PER_SEC 200
707
708
static void snd_cs46xx_set_play_sample_rate(struct snd_cs46xx *chip, unsigned int rate)
709
{
710
unsigned int tmp1, tmp2;
711
unsigned int phiIncr;
712
unsigned int correctionPerGOF, correctionPerSec;
713
714
/*
715
* Compute the values used to drive the actual sample rate conversion.
716
* The following formulas are being computed, using inline assembly
717
* since we need to use 64 bit arithmetic to compute the values:
718
*
719
* phiIncr = floor((Fs,in * 2^26) / Fs,out)
720
* correctionPerGOF = floor((Fs,in * 2^26 - Fs,out * phiIncr) /
721
* GOF_PER_SEC)
722
* ulCorrectionPerSec = Fs,in * 2^26 - Fs,out * phiIncr -M
723
* GOF_PER_SEC * correctionPerGOF
724
*
725
* i.e.
726
*
727
* phiIncr:other = dividend:remainder((Fs,in * 2^26) / Fs,out)
728
* correctionPerGOF:correctionPerSec =
729
* dividend:remainder(ulOther / GOF_PER_SEC)
730
*/
731
tmp1 = rate << 16;
732
phiIncr = tmp1 / 48000;
733
tmp1 -= phiIncr * 48000;
734
tmp1 <<= 10;
735
phiIncr <<= 10;
736
tmp2 = tmp1 / 48000;
737
phiIncr += tmp2;
738
tmp1 -= tmp2 * 48000;
739
correctionPerGOF = tmp1 / GOF_PER_SEC;
740
tmp1 -= correctionPerGOF * GOF_PER_SEC;
741
correctionPerSec = tmp1;
742
743
/*
744
* Fill in the SampleRateConverter control block.
745
*/
746
guard(spinlock_irqsave)(&chip->reg_lock);
747
snd_cs46xx_poke(chip, BA1_PSRC,
748
((correctionPerSec << 16) & 0xFFFF0000) | (correctionPerGOF & 0xFFFF));
749
snd_cs46xx_poke(chip, BA1_PPI, phiIncr);
750
}
751
752
static void snd_cs46xx_set_capture_sample_rate(struct snd_cs46xx *chip, unsigned int rate)
753
{
754
unsigned int phiIncr, coeffIncr, tmp1, tmp2;
755
unsigned int correctionPerGOF, correctionPerSec, initialDelay;
756
unsigned int frameGroupLength, cnt;
757
758
/*
759
* We can only decimate by up to a factor of 1/9th the hardware rate.
760
* Correct the value if an attempt is made to stray outside that limit.
761
*/
762
if ((rate * 9) < 48000)
763
rate = 48000 / 9;
764
765
/*
766
* We can not capture at a rate greater than the Input Rate (48000).
767
* Return an error if an attempt is made to stray outside that limit.
768
*/
769
if (rate > 48000)
770
rate = 48000;
771
772
/*
773
* Compute the values used to drive the actual sample rate conversion.
774
* The following formulas are being computed, using inline assembly
775
* since we need to use 64 bit arithmetic to compute the values:
776
*
777
* coeffIncr = -floor((Fs,out * 2^23) / Fs,in)
778
* phiIncr = floor((Fs,in * 2^26) / Fs,out)
779
* correctionPerGOF = floor((Fs,in * 2^26 - Fs,out * phiIncr) /
780
* GOF_PER_SEC)
781
* correctionPerSec = Fs,in * 2^26 - Fs,out * phiIncr -
782
* GOF_PER_SEC * correctionPerGOF
783
* initialDelay = ceil((24 * Fs,in) / Fs,out)
784
*
785
* i.e.
786
*
787
* coeffIncr = neg(dividend((Fs,out * 2^23) / Fs,in))
788
* phiIncr:ulOther = dividend:remainder((Fs,in * 2^26) / Fs,out)
789
* correctionPerGOF:correctionPerSec =
790
* dividend:remainder(ulOther / GOF_PER_SEC)
791
* initialDelay = dividend(((24 * Fs,in) + Fs,out - 1) / Fs,out)
792
*/
793
794
tmp1 = rate << 16;
795
coeffIncr = tmp1 / 48000;
796
tmp1 -= coeffIncr * 48000;
797
tmp1 <<= 7;
798
coeffIncr <<= 7;
799
coeffIncr += tmp1 / 48000;
800
coeffIncr ^= 0xFFFFFFFF;
801
coeffIncr++;
802
tmp1 = 48000 << 16;
803
phiIncr = tmp1 / rate;
804
tmp1 -= phiIncr * rate;
805
tmp1 <<= 10;
806
phiIncr <<= 10;
807
tmp2 = tmp1 / rate;
808
phiIncr += tmp2;
809
tmp1 -= tmp2 * rate;
810
correctionPerGOF = tmp1 / GOF_PER_SEC;
811
tmp1 -= correctionPerGOF * GOF_PER_SEC;
812
correctionPerSec = tmp1;
813
initialDelay = DIV_ROUND_UP(48000 * 24, rate);
814
815
/*
816
* Fill in the VariDecimate control block.
817
*/
818
scoped_guard(spinlock_irqsave, &chip->reg_lock) {
819
snd_cs46xx_poke(chip, BA1_CSRC,
820
((correctionPerSec << 16) & 0xFFFF0000) | (correctionPerGOF & 0xFFFF));
821
snd_cs46xx_poke(chip, BA1_CCI, coeffIncr);
822
snd_cs46xx_poke(chip, BA1_CD,
823
(((BA1_VARIDEC_BUF_1 + (initialDelay << 2)) << 16) & 0xFFFF0000) | 0x80);
824
snd_cs46xx_poke(chip, BA1_CPI, phiIncr);
825
}
826
827
/*
828
* Figure out the frame group length for the write back task. Basically,
829
* this is just the factors of 24000 (2^6*3*5^3) that are not present in
830
* the output sample rate.
831
*/
832
frameGroupLength = 1;
833
for (cnt = 2; cnt <= 64; cnt *= 2) {
834
if (((rate / cnt) * cnt) != rate)
835
frameGroupLength *= 2;
836
}
837
if (((rate / 3) * 3) != rate) {
838
frameGroupLength *= 3;
839
}
840
for (cnt = 5; cnt <= 125; cnt *= 5) {
841
if (((rate / cnt) * cnt) != rate)
842
frameGroupLength *= 5;
843
}
844
845
/*
846
* Fill in the WriteBack control block.
847
*/
848
guard(spinlock_irqsave)(&chip->reg_lock);
849
snd_cs46xx_poke(chip, BA1_CFG1, frameGroupLength);
850
snd_cs46xx_poke(chip, BA1_CFG2, (0x00800000 | frameGroupLength));
851
snd_cs46xx_poke(chip, BA1_CCST, 0x0000FFFF);
852
snd_cs46xx_poke(chip, BA1_CSPB, ((65536 * rate) / 24000));
853
snd_cs46xx_poke(chip, (BA1_CSPB + 4), 0x0000FFFF);
854
}
855
856
/*
857
* PCM part
858
*/
859
860
static void snd_cs46xx_pb_trans_copy(struct snd_pcm_substream *substream,
861
struct snd_pcm_indirect *rec, size_t bytes)
862
{
863
struct snd_pcm_runtime *runtime = substream->runtime;
864
struct snd_cs46xx_pcm * cpcm = runtime->private_data;
865
memcpy(cpcm->hw_buf.area + rec->hw_data, runtime->dma_area + rec->sw_data, bytes);
866
}
867
868
static int snd_cs46xx_playback_transfer(struct snd_pcm_substream *substream)
869
{
870
struct snd_pcm_runtime *runtime = substream->runtime;
871
struct snd_cs46xx_pcm * cpcm = runtime->private_data;
872
return snd_pcm_indirect_playback_transfer(substream, &cpcm->pcm_rec,
873
snd_cs46xx_pb_trans_copy);
874
}
875
876
static void snd_cs46xx_cp_trans_copy(struct snd_pcm_substream *substream,
877
struct snd_pcm_indirect *rec, size_t bytes)
878
{
879
struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
880
struct snd_pcm_runtime *runtime = substream->runtime;
881
memcpy(runtime->dma_area + rec->sw_data,
882
chip->capt.hw_buf.area + rec->hw_data, bytes);
883
}
884
885
static int snd_cs46xx_capture_transfer(struct snd_pcm_substream *substream)
886
{
887
struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
888
return snd_pcm_indirect_capture_transfer(substream, &chip->capt.pcm_rec,
889
snd_cs46xx_cp_trans_copy);
890
}
891
892
static snd_pcm_uframes_t snd_cs46xx_playback_direct_pointer(struct snd_pcm_substream *substream)
893
{
894
struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
895
size_t ptr;
896
struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data;
897
898
if (snd_BUG_ON(!cpcm->pcm_channel))
899
return -ENXIO;
900
901
#ifdef CONFIG_SND_CS46XX_NEW_DSP
902
ptr = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 2) << 2);
903
#else
904
ptr = snd_cs46xx_peek(chip, BA1_PBA);
905
#endif
906
ptr -= cpcm->hw_buf.addr;
907
return ptr >> cpcm->shift;
908
}
909
910
static snd_pcm_uframes_t snd_cs46xx_playback_indirect_pointer(struct snd_pcm_substream *substream)
911
{
912
struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
913
size_t ptr;
914
struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data;
915
916
#ifdef CONFIG_SND_CS46XX_NEW_DSP
917
if (snd_BUG_ON(!cpcm->pcm_channel))
918
return -ENXIO;
919
ptr = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 2) << 2);
920
#else
921
ptr = snd_cs46xx_peek(chip, BA1_PBA);
922
#endif
923
ptr -= cpcm->hw_buf.addr;
924
return snd_pcm_indirect_playback_pointer(substream, &cpcm->pcm_rec, ptr);
925
}
926
927
static snd_pcm_uframes_t snd_cs46xx_capture_direct_pointer(struct snd_pcm_substream *substream)
928
{
929
struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
930
size_t ptr = snd_cs46xx_peek(chip, BA1_CBA) - chip->capt.hw_buf.addr;
931
return ptr >> chip->capt.shift;
932
}
933
934
static snd_pcm_uframes_t snd_cs46xx_capture_indirect_pointer(struct snd_pcm_substream *substream)
935
{
936
struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
937
size_t ptr = snd_cs46xx_peek(chip, BA1_CBA) - chip->capt.hw_buf.addr;
938
return snd_pcm_indirect_capture_pointer(substream, &chip->capt.pcm_rec, ptr);
939
}
940
941
static int snd_cs46xx_playback_trigger(struct snd_pcm_substream *substream,
942
int cmd)
943
{
944
struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
945
/*struct snd_pcm_runtime *runtime = substream->runtime;*/
946
int result = 0;
947
948
#ifdef CONFIG_SND_CS46XX_NEW_DSP
949
struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data;
950
if (! cpcm->pcm_channel) {
951
return -ENXIO;
952
}
953
#endif
954
switch (cmd) {
955
case SNDRV_PCM_TRIGGER_START:
956
case SNDRV_PCM_TRIGGER_RESUME:
957
#ifdef CONFIG_SND_CS46XX_NEW_DSP
958
/* magic value to unmute PCM stream playback volume */
959
snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address +
960
SCBVolumeCtrl) << 2, 0x80008000);
961
962
if (cpcm->pcm_channel->unlinked)
963
cs46xx_dsp_pcm_link(chip,cpcm->pcm_channel);
964
965
if (substream->runtime->periods != CS46XX_FRAGS)
966
snd_cs46xx_playback_transfer(substream);
967
#else
968
scoped_guard(spinlock, &chip->reg_lock) {
969
unsigned int tmp;
970
if (substream->runtime->periods != CS46XX_FRAGS)
971
snd_cs46xx_playback_transfer(substream);
972
tmp = snd_cs46xx_peek(chip, BA1_PCTL);
973
tmp &= 0x0000ffff;
974
snd_cs46xx_poke(chip, BA1_PCTL, chip->play_ctl | tmp);
975
}
976
#endif
977
break;
978
case SNDRV_PCM_TRIGGER_STOP:
979
case SNDRV_PCM_TRIGGER_SUSPEND:
980
#ifdef CONFIG_SND_CS46XX_NEW_DSP
981
/* magic mute channel */
982
snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address +
983
SCBVolumeCtrl) << 2, 0xffffffff);
984
985
if (!cpcm->pcm_channel->unlinked)
986
cs46xx_dsp_pcm_unlink(chip,cpcm->pcm_channel);
987
#else
988
scoped_guard(spinlock, &chip->reg_lock) {
989
unsigned int tmp;
990
tmp = snd_cs46xx_peek(chip, BA1_PCTL);
991
tmp &= 0x0000ffff;
992
snd_cs46xx_poke(chip, BA1_PCTL, tmp);
993
}
994
#endif
995
break;
996
default:
997
result = -EINVAL;
998
break;
999
}
1000
1001
return result;
1002
}
1003
1004
static int snd_cs46xx_capture_trigger(struct snd_pcm_substream *substream,
1005
int cmd)
1006
{
1007
struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
1008
unsigned int tmp;
1009
1010
guard(spinlock)(&chip->reg_lock);
1011
switch (cmd) {
1012
case SNDRV_PCM_TRIGGER_START:
1013
case SNDRV_PCM_TRIGGER_RESUME:
1014
tmp = snd_cs46xx_peek(chip, BA1_CCTL);
1015
tmp &= 0xffff0000;
1016
snd_cs46xx_poke(chip, BA1_CCTL, chip->capt.ctl | tmp);
1017
break;
1018
case SNDRV_PCM_TRIGGER_STOP:
1019
case SNDRV_PCM_TRIGGER_SUSPEND:
1020
tmp = snd_cs46xx_peek(chip, BA1_CCTL);
1021
tmp &= 0xffff0000;
1022
snd_cs46xx_poke(chip, BA1_CCTL, tmp);
1023
break;
1024
default:
1025
return -EINVAL;
1026
}
1027
return 0;
1028
}
1029
1030
#ifdef CONFIG_SND_CS46XX_NEW_DSP
1031
static int _cs46xx_adjust_sample_rate (struct snd_cs46xx *chip, struct snd_cs46xx_pcm *cpcm,
1032
int sample_rate)
1033
{
1034
1035
/* If PCMReaderSCB and SrcTaskSCB not created yet ... */
1036
if ( cpcm->pcm_channel == NULL) {
1037
cpcm->pcm_channel = cs46xx_dsp_create_pcm_channel (chip, sample_rate,
1038
cpcm, cpcm->hw_buf.addr,cpcm->pcm_channel_id);
1039
if (cpcm->pcm_channel == NULL) {
1040
dev_err(chip->card->dev,
1041
"failed to create virtual PCM channel\n");
1042
return -ENOMEM;
1043
}
1044
cpcm->pcm_channel->sample_rate = sample_rate;
1045
} else
1046
/* if sample rate is changed */
1047
if ((int)cpcm->pcm_channel->sample_rate != sample_rate) {
1048
int unlinked = cpcm->pcm_channel->unlinked;
1049
cs46xx_dsp_destroy_pcm_channel (chip,cpcm->pcm_channel);
1050
1051
cpcm->pcm_channel = cs46xx_dsp_create_pcm_channel(chip, sample_rate, cpcm,
1052
cpcm->hw_buf.addr,
1053
cpcm->pcm_channel_id);
1054
if (!cpcm->pcm_channel) {
1055
dev_err(chip->card->dev,
1056
"failed to re-create virtual PCM channel\n");
1057
return -ENOMEM;
1058
}
1059
1060
if (!unlinked) cs46xx_dsp_pcm_link (chip,cpcm->pcm_channel);
1061
cpcm->pcm_channel->sample_rate = sample_rate;
1062
}
1063
1064
return 0;
1065
}
1066
#endif
1067
1068
1069
static int snd_cs46xx_playback_hw_params(struct snd_pcm_substream *substream,
1070
struct snd_pcm_hw_params *hw_params)
1071
{
1072
struct snd_pcm_runtime *runtime = substream->runtime;
1073
struct snd_cs46xx_pcm *cpcm;
1074
int err;
1075
#ifdef CONFIG_SND_CS46XX_NEW_DSP
1076
struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
1077
int sample_rate = params_rate(hw_params);
1078
int period_size = params_period_bytes(hw_params);
1079
#endif
1080
cpcm = runtime->private_data;
1081
1082
#ifdef CONFIG_SND_CS46XX_NEW_DSP
1083
if (snd_BUG_ON(!sample_rate))
1084
return -ENXIO;
1085
1086
guard(mutex)(&chip->spos_mutex);
1087
1088
if (_cs46xx_adjust_sample_rate(chip, cpcm, sample_rate))
1089
return -ENXIO;
1090
1091
snd_BUG_ON(!cpcm->pcm_channel);
1092
if (!cpcm->pcm_channel)
1093
return -ENXIO;
1094
1095
if (cs46xx_dsp_pcm_channel_set_period(chip, cpcm->pcm_channel, period_size))
1096
return -EINVAL;
1097
1098
dev_dbg(chip->card->dev,
1099
"period_size (%d), periods (%d) buffer_size(%d)\n",
1100
period_size, params_periods(hw_params),
1101
params_buffer_bytes(hw_params));
1102
#endif
1103
1104
if (params_periods(hw_params) == CS46XX_FRAGS) {
1105
if (runtime->dma_area != cpcm->hw_buf.area)
1106
snd_pcm_lib_free_pages(substream);
1107
snd_pcm_set_runtime_buffer(substream, &cpcm->hw_buf);
1108
1109
1110
#ifdef CONFIG_SND_CS46XX_NEW_DSP
1111
if (cpcm->pcm_channel_id == DSP_PCM_MAIN_CHANNEL) {
1112
substream->ops = &snd_cs46xx_playback_ops;
1113
} else if (cpcm->pcm_channel_id == DSP_PCM_REAR_CHANNEL) {
1114
substream->ops = &snd_cs46xx_playback_rear_ops;
1115
} else if (cpcm->pcm_channel_id == DSP_PCM_CENTER_LFE_CHANNEL) {
1116
substream->ops = &snd_cs46xx_playback_clfe_ops;
1117
} else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) {
1118
substream->ops = &snd_cs46xx_playback_iec958_ops;
1119
} else {
1120
snd_BUG();
1121
}
1122
#else
1123
substream->ops = &snd_cs46xx_playback_ops;
1124
#endif
1125
1126
} else {
1127
if (runtime->dma_area == cpcm->hw_buf.area)
1128
snd_pcm_set_runtime_buffer(substream, NULL);
1129
err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
1130
if (err < 0)
1131
return err;
1132
1133
#ifdef CONFIG_SND_CS46XX_NEW_DSP
1134
if (cpcm->pcm_channel_id == DSP_PCM_MAIN_CHANNEL) {
1135
substream->ops = &snd_cs46xx_playback_indirect_ops;
1136
} else if (cpcm->pcm_channel_id == DSP_PCM_REAR_CHANNEL) {
1137
substream->ops = &snd_cs46xx_playback_indirect_rear_ops;
1138
} else if (cpcm->pcm_channel_id == DSP_PCM_CENTER_LFE_CHANNEL) {
1139
substream->ops = &snd_cs46xx_playback_indirect_clfe_ops;
1140
} else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) {
1141
substream->ops = &snd_cs46xx_playback_indirect_iec958_ops;
1142
} else {
1143
snd_BUG();
1144
}
1145
#else
1146
substream->ops = &snd_cs46xx_playback_indirect_ops;
1147
#endif
1148
1149
}
1150
1151
return 0;
1152
}
1153
1154
static int snd_cs46xx_playback_hw_free(struct snd_pcm_substream *substream)
1155
{
1156
/*struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);*/
1157
struct snd_pcm_runtime *runtime = substream->runtime;
1158
struct snd_cs46xx_pcm *cpcm;
1159
1160
cpcm = runtime->private_data;
1161
1162
/* if play_back open fails, then this function
1163
is called and cpcm can actually be NULL here */
1164
if (!cpcm) return -ENXIO;
1165
1166
if (runtime->dma_area != cpcm->hw_buf.area)
1167
snd_pcm_lib_free_pages(substream);
1168
1169
snd_pcm_set_runtime_buffer(substream, NULL);
1170
1171
return 0;
1172
}
1173
1174
static int snd_cs46xx_playback_prepare(struct snd_pcm_substream *substream)
1175
{
1176
unsigned int tmp;
1177
unsigned int pfie;
1178
struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
1179
struct snd_pcm_runtime *runtime = substream->runtime;
1180
struct snd_cs46xx_pcm *cpcm;
1181
1182
cpcm = runtime->private_data;
1183
1184
#ifdef CONFIG_SND_CS46XX_NEW_DSP
1185
if (snd_BUG_ON(!cpcm->pcm_channel))
1186
return -ENXIO;
1187
1188
pfie = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 1) << 2 );
1189
pfie &= ~0x0000f03f;
1190
#else
1191
/* old dsp */
1192
pfie = snd_cs46xx_peek(chip, BA1_PFIE);
1193
pfie &= ~0x0000f03f;
1194
#endif
1195
1196
cpcm->shift = 2;
1197
/* if to convert from stereo to mono */
1198
if (runtime->channels == 1) {
1199
cpcm->shift--;
1200
pfie |= 0x00002000;
1201
}
1202
/* if to convert from 8 bit to 16 bit */
1203
if (snd_pcm_format_width(runtime->format) == 8) {
1204
cpcm->shift--;
1205
pfie |= 0x00001000;
1206
}
1207
/* if to convert to unsigned */
1208
if (snd_pcm_format_unsigned(runtime->format))
1209
pfie |= 0x00008000;
1210
1211
/* Never convert byte order when sample stream is 8 bit */
1212
if (snd_pcm_format_width(runtime->format) != 8) {
1213
/* convert from big endian to little endian */
1214
if (snd_pcm_format_big_endian(runtime->format))
1215
pfie |= 0x00004000;
1216
}
1217
1218
memset(&cpcm->pcm_rec, 0, sizeof(cpcm->pcm_rec));
1219
cpcm->pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream);
1220
cpcm->pcm_rec.hw_buffer_size = runtime->period_size * CS46XX_FRAGS << cpcm->shift;
1221
1222
#ifdef CONFIG_SND_CS46XX_NEW_DSP
1223
1224
tmp = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address) << 2);
1225
tmp &= ~0x000003ff;
1226
tmp |= (4 << cpcm->shift) - 1;
1227
/* playback transaction count register */
1228
snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address) << 2, tmp);
1229
1230
/* playback format && interrupt enable */
1231
snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 1) << 2, pfie | cpcm->pcm_channel->pcm_slot);
1232
#else
1233
snd_cs46xx_poke(chip, BA1_PBA, cpcm->hw_buf.addr);
1234
tmp = snd_cs46xx_peek(chip, BA1_PDTC);
1235
tmp &= ~0x000003ff;
1236
tmp |= (4 << cpcm->shift) - 1;
1237
snd_cs46xx_poke(chip, BA1_PDTC, tmp);
1238
snd_cs46xx_poke(chip, BA1_PFIE, pfie);
1239
snd_cs46xx_set_play_sample_rate(chip, runtime->rate);
1240
#endif
1241
1242
return 0;
1243
}
1244
1245
static int snd_cs46xx_capture_hw_params(struct snd_pcm_substream *substream,
1246
struct snd_pcm_hw_params *hw_params)
1247
{
1248
struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
1249
struct snd_pcm_runtime *runtime = substream->runtime;
1250
int err;
1251
1252
#ifdef CONFIG_SND_CS46XX_NEW_DSP
1253
cs46xx_dsp_pcm_ostream_set_period (chip, params_period_bytes(hw_params));
1254
#endif
1255
if (runtime->periods == CS46XX_FRAGS) {
1256
if (runtime->dma_area != chip->capt.hw_buf.area)
1257
snd_pcm_lib_free_pages(substream);
1258
snd_pcm_set_runtime_buffer(substream, &chip->capt.hw_buf);
1259
substream->ops = &snd_cs46xx_capture_ops;
1260
} else {
1261
if (runtime->dma_area == chip->capt.hw_buf.area)
1262
snd_pcm_set_runtime_buffer(substream, NULL);
1263
err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
1264
if (err < 0)
1265
return err;
1266
substream->ops = &snd_cs46xx_capture_indirect_ops;
1267
}
1268
1269
return 0;
1270
}
1271
1272
static int snd_cs46xx_capture_hw_free(struct snd_pcm_substream *substream)
1273
{
1274
struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
1275
struct snd_pcm_runtime *runtime = substream->runtime;
1276
1277
if (runtime->dma_area != chip->capt.hw_buf.area)
1278
snd_pcm_lib_free_pages(substream);
1279
snd_pcm_set_runtime_buffer(substream, NULL);
1280
1281
return 0;
1282
}
1283
1284
static int snd_cs46xx_capture_prepare(struct snd_pcm_substream *substream)
1285
{
1286
struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
1287
struct snd_pcm_runtime *runtime = substream->runtime;
1288
1289
snd_cs46xx_poke(chip, BA1_CBA, chip->capt.hw_buf.addr);
1290
chip->capt.shift = 2;
1291
memset(&chip->capt.pcm_rec, 0, sizeof(chip->capt.pcm_rec));
1292
chip->capt.pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream);
1293
chip->capt.pcm_rec.hw_buffer_size = runtime->period_size * CS46XX_FRAGS << 2;
1294
snd_cs46xx_set_capture_sample_rate(chip, runtime->rate);
1295
1296
return 0;
1297
}
1298
1299
static irqreturn_t snd_cs46xx_interrupt(int irq, void *dev_id)
1300
{
1301
struct snd_cs46xx *chip = dev_id;
1302
u32 status1;
1303
#ifdef CONFIG_SND_CS46XX_NEW_DSP
1304
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
1305
u32 status2;
1306
int i;
1307
struct snd_cs46xx_pcm *cpcm = NULL;
1308
#endif
1309
1310
/*
1311
* Read the Interrupt Status Register to clear the interrupt
1312
*/
1313
status1 = snd_cs46xx_peekBA0(chip, BA0_HISR);
1314
if ((status1 & 0x7fffffff) == 0) {
1315
snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_CHGM | HICR_IEV);
1316
return IRQ_NONE;
1317
}
1318
1319
#ifdef CONFIG_SND_CS46XX_NEW_DSP
1320
status2 = snd_cs46xx_peekBA0(chip, BA0_HSR0);
1321
1322
for (i = 0; i < DSP_MAX_PCM_CHANNELS; ++i) {
1323
if (i <= 15) {
1324
if ( status1 & (1 << i) ) {
1325
if (i == CS46XX_DSP_CAPTURE_CHANNEL) {
1326
if (chip->capt.substream)
1327
snd_pcm_period_elapsed(chip->capt.substream);
1328
} else {
1329
if (ins->pcm_channels[i].active &&
1330
ins->pcm_channels[i].private_data &&
1331
!ins->pcm_channels[i].unlinked) {
1332
cpcm = ins->pcm_channels[i].private_data;
1333
snd_pcm_period_elapsed(cpcm->substream);
1334
}
1335
}
1336
}
1337
} else {
1338
if ( status2 & (1 << (i - 16))) {
1339
if (ins->pcm_channels[i].active &&
1340
ins->pcm_channels[i].private_data &&
1341
!ins->pcm_channels[i].unlinked) {
1342
cpcm = ins->pcm_channels[i].private_data;
1343
snd_pcm_period_elapsed(cpcm->substream);
1344
}
1345
}
1346
}
1347
}
1348
1349
#else
1350
/* old dsp */
1351
if ((status1 & HISR_VC0) && chip->playback_pcm) {
1352
if (chip->playback_pcm->substream)
1353
snd_pcm_period_elapsed(chip->playback_pcm->substream);
1354
}
1355
if ((status1 & HISR_VC1) && chip->pcm) {
1356
if (chip->capt.substream)
1357
snd_pcm_period_elapsed(chip->capt.substream);
1358
}
1359
#endif
1360
1361
if ((status1 & HISR_MIDI) && chip->rmidi) {
1362
unsigned char c;
1363
1364
guard(spinlock)(&chip->reg_lock);
1365
while ((snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_RBE) == 0) {
1366
c = snd_cs46xx_peekBA0(chip, BA0_MIDRP);
1367
if ((chip->midcr & MIDCR_RIE) == 0)
1368
continue;
1369
snd_rawmidi_receive(chip->midi_input, &c, 1);
1370
}
1371
while ((snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_TBF) == 0) {
1372
if ((chip->midcr & MIDCR_TIE) == 0)
1373
break;
1374
if (snd_rawmidi_transmit(chip->midi_output, &c, 1) != 1) {
1375
chip->midcr &= ~MIDCR_TIE;
1376
snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
1377
break;
1378
}
1379
snd_cs46xx_pokeBA0(chip, BA0_MIDWP, c);
1380
}
1381
}
1382
/*
1383
* EOI to the PCI part....reenables interrupts
1384
*/
1385
snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_CHGM | HICR_IEV);
1386
1387
return IRQ_HANDLED;
1388
}
1389
1390
static const struct snd_pcm_hardware snd_cs46xx_playback =
1391
{
1392
.info = (SNDRV_PCM_INFO_MMAP |
1393
SNDRV_PCM_INFO_INTERLEAVED |
1394
SNDRV_PCM_INFO_BLOCK_TRANSFER /*|*/
1395
/*SNDRV_PCM_INFO_RESUME*/ |
1396
SNDRV_PCM_INFO_SYNC_APPLPTR),
1397
.formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
1398
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |
1399
SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE),
1400
.rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
1401
.rate_min = 5500,
1402
.rate_max = 48000,
1403
.channels_min = 1,
1404
.channels_max = 2,
1405
.buffer_bytes_max = (256 * 1024),
1406
.period_bytes_min = CS46XX_MIN_PERIOD_SIZE,
1407
.period_bytes_max = CS46XX_MAX_PERIOD_SIZE,
1408
.periods_min = CS46XX_FRAGS,
1409
.periods_max = 1024,
1410
.fifo_size = 0,
1411
};
1412
1413
static const struct snd_pcm_hardware snd_cs46xx_capture =
1414
{
1415
.info = (SNDRV_PCM_INFO_MMAP |
1416
SNDRV_PCM_INFO_INTERLEAVED |
1417
SNDRV_PCM_INFO_BLOCK_TRANSFER /*|*/
1418
/*SNDRV_PCM_INFO_RESUME*/ |
1419
SNDRV_PCM_INFO_SYNC_APPLPTR),
1420
.formats = SNDRV_PCM_FMTBIT_S16_LE,
1421
.rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
1422
.rate_min = 5500,
1423
.rate_max = 48000,
1424
.channels_min = 2,
1425
.channels_max = 2,
1426
.buffer_bytes_max = (256 * 1024),
1427
.period_bytes_min = CS46XX_MIN_PERIOD_SIZE,
1428
.period_bytes_max = CS46XX_MAX_PERIOD_SIZE,
1429
.periods_min = CS46XX_FRAGS,
1430
.periods_max = 1024,
1431
.fifo_size = 0,
1432
};
1433
1434
#ifdef CONFIG_SND_CS46XX_NEW_DSP
1435
1436
static const unsigned int period_sizes[] = { 32, 64, 128, 256, 512, 1024, 2048 };
1437
1438
static const struct snd_pcm_hw_constraint_list hw_constraints_period_sizes = {
1439
.count = ARRAY_SIZE(period_sizes),
1440
.list = period_sizes,
1441
.mask = 0
1442
};
1443
1444
#endif
1445
1446
static void snd_cs46xx_pcm_free_substream(struct snd_pcm_runtime *runtime)
1447
{
1448
kfree(runtime->private_data);
1449
}
1450
1451
static int _cs46xx_playback_open_channel (struct snd_pcm_substream *substream,int pcm_channel_id)
1452
{
1453
struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
1454
struct snd_cs46xx_pcm * cpcm;
1455
struct snd_pcm_runtime *runtime = substream->runtime;
1456
1457
cpcm = kzalloc(sizeof(*cpcm), GFP_KERNEL);
1458
if (cpcm == NULL)
1459
return -ENOMEM;
1460
if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &chip->pci->dev,
1461
PAGE_SIZE, &cpcm->hw_buf) < 0) {
1462
kfree(cpcm);
1463
return -ENOMEM;
1464
}
1465
1466
runtime->hw = snd_cs46xx_playback;
1467
runtime->private_data = cpcm;
1468
runtime->private_free = snd_cs46xx_pcm_free_substream;
1469
1470
cpcm->substream = substream;
1471
#ifdef CONFIG_SND_CS46XX_NEW_DSP
1472
scoped_guard(mutex, &chip->spos_mutex) {
1473
cpcm->pcm_channel = NULL;
1474
cpcm->pcm_channel_id = pcm_channel_id;
1475
}
1476
1477
snd_pcm_hw_constraint_list(runtime, 0,
1478
SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
1479
&hw_constraints_period_sizes);
1480
#else
1481
chip->playback_pcm = cpcm; /* HACK */
1482
#endif
1483
1484
if (chip->accept_valid)
1485
substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID;
1486
chip->active_ctrl(chip, 1);
1487
1488
return 0;
1489
}
1490
1491
static int snd_cs46xx_playback_open(struct snd_pcm_substream *substream)
1492
{
1493
dev_dbg(substream->pcm->card->dev, "open front channel\n");
1494
return _cs46xx_playback_open_channel(substream,DSP_PCM_MAIN_CHANNEL);
1495
}
1496
1497
#ifdef CONFIG_SND_CS46XX_NEW_DSP
1498
static int snd_cs46xx_playback_open_rear(struct snd_pcm_substream *substream)
1499
{
1500
dev_dbg(substream->pcm->card->dev, "open rear channel\n");
1501
return _cs46xx_playback_open_channel(substream,DSP_PCM_REAR_CHANNEL);
1502
}
1503
1504
static int snd_cs46xx_playback_open_clfe(struct snd_pcm_substream *substream)
1505
{
1506
dev_dbg(substream->pcm->card->dev, "open center - LFE channel\n");
1507
return _cs46xx_playback_open_channel(substream,DSP_PCM_CENTER_LFE_CHANNEL);
1508
}
1509
1510
static int snd_cs46xx_playback_open_iec958(struct snd_pcm_substream *substream)
1511
{
1512
struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
1513
1514
dev_dbg(chip->card->dev, "open raw iec958 channel\n");
1515
1516
scoped_guard(mutex, &chip->spos_mutex) {
1517
cs46xx_iec958_pre_open(chip);
1518
}
1519
1520
return _cs46xx_playback_open_channel(substream,DSP_IEC958_CHANNEL);
1521
}
1522
1523
static int snd_cs46xx_playback_close(struct snd_pcm_substream *substream);
1524
1525
static int snd_cs46xx_playback_close_iec958(struct snd_pcm_substream *substream)
1526
{
1527
int err;
1528
struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
1529
1530
dev_dbg(chip->card->dev, "close raw iec958 channel\n");
1531
1532
err = snd_cs46xx_playback_close(substream);
1533
1534
scoped_guard(mutex, &chip->spos_mutex) {
1535
cs46xx_iec958_post_close(chip);
1536
}
1537
1538
return err;
1539
}
1540
#endif
1541
1542
static int snd_cs46xx_capture_open(struct snd_pcm_substream *substream)
1543
{
1544
struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
1545
1546
if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &chip->pci->dev,
1547
PAGE_SIZE, &chip->capt.hw_buf) < 0)
1548
return -ENOMEM;
1549
chip->capt.substream = substream;
1550
substream->runtime->hw = snd_cs46xx_capture;
1551
1552
if (chip->accept_valid)
1553
substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID;
1554
1555
chip->active_ctrl(chip, 1);
1556
1557
#ifdef CONFIG_SND_CS46XX_NEW_DSP
1558
snd_pcm_hw_constraint_list(substream->runtime, 0,
1559
SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
1560
&hw_constraints_period_sizes);
1561
#endif
1562
return 0;
1563
}
1564
1565
static int snd_cs46xx_playback_close(struct snd_pcm_substream *substream)
1566
{
1567
struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
1568
struct snd_pcm_runtime *runtime = substream->runtime;
1569
struct snd_cs46xx_pcm * cpcm;
1570
1571
cpcm = runtime->private_data;
1572
1573
/* when playback_open fails, then cpcm can be NULL */
1574
if (!cpcm) return -ENXIO;
1575
1576
#ifdef CONFIG_SND_CS46XX_NEW_DSP
1577
scoped_guard(mutex, &chip->spos_mutex) {
1578
if (cpcm->pcm_channel) {
1579
cs46xx_dsp_destroy_pcm_channel(chip, cpcm->pcm_channel);
1580
cpcm->pcm_channel = NULL;
1581
}
1582
}
1583
#else
1584
chip->playback_pcm = NULL;
1585
#endif
1586
1587
cpcm->substream = NULL;
1588
snd_dma_free_pages(&cpcm->hw_buf);
1589
chip->active_ctrl(chip, -1);
1590
1591
return 0;
1592
}
1593
1594
static int snd_cs46xx_capture_close(struct snd_pcm_substream *substream)
1595
{
1596
struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
1597
1598
chip->capt.substream = NULL;
1599
snd_dma_free_pages(&chip->capt.hw_buf);
1600
chip->active_ctrl(chip, -1);
1601
1602
return 0;
1603
}
1604
1605
#ifdef CONFIG_SND_CS46XX_NEW_DSP
1606
static const struct snd_pcm_ops snd_cs46xx_playback_rear_ops = {
1607
.open = snd_cs46xx_playback_open_rear,
1608
.close = snd_cs46xx_playback_close,
1609
.hw_params = snd_cs46xx_playback_hw_params,
1610
.hw_free = snd_cs46xx_playback_hw_free,
1611
.prepare = snd_cs46xx_playback_prepare,
1612
.trigger = snd_cs46xx_playback_trigger,
1613
.pointer = snd_cs46xx_playback_direct_pointer,
1614
};
1615
1616
static const struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops = {
1617
.open = snd_cs46xx_playback_open_rear,
1618
.close = snd_cs46xx_playback_close,
1619
.hw_params = snd_cs46xx_playback_hw_params,
1620
.hw_free = snd_cs46xx_playback_hw_free,
1621
.prepare = snd_cs46xx_playback_prepare,
1622
.trigger = snd_cs46xx_playback_trigger,
1623
.pointer = snd_cs46xx_playback_indirect_pointer,
1624
.ack = snd_cs46xx_playback_transfer,
1625
};
1626
1627
static const struct snd_pcm_ops snd_cs46xx_playback_clfe_ops = {
1628
.open = snd_cs46xx_playback_open_clfe,
1629
.close = snd_cs46xx_playback_close,
1630
.hw_params = snd_cs46xx_playback_hw_params,
1631
.hw_free = snd_cs46xx_playback_hw_free,
1632
.prepare = snd_cs46xx_playback_prepare,
1633
.trigger = snd_cs46xx_playback_trigger,
1634
.pointer = snd_cs46xx_playback_direct_pointer,
1635
};
1636
1637
static const struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops = {
1638
.open = snd_cs46xx_playback_open_clfe,
1639
.close = snd_cs46xx_playback_close,
1640
.hw_params = snd_cs46xx_playback_hw_params,
1641
.hw_free = snd_cs46xx_playback_hw_free,
1642
.prepare = snd_cs46xx_playback_prepare,
1643
.trigger = snd_cs46xx_playback_trigger,
1644
.pointer = snd_cs46xx_playback_indirect_pointer,
1645
.ack = snd_cs46xx_playback_transfer,
1646
};
1647
1648
static const struct snd_pcm_ops snd_cs46xx_playback_iec958_ops = {
1649
.open = snd_cs46xx_playback_open_iec958,
1650
.close = snd_cs46xx_playback_close_iec958,
1651
.hw_params = snd_cs46xx_playback_hw_params,
1652
.hw_free = snd_cs46xx_playback_hw_free,
1653
.prepare = snd_cs46xx_playback_prepare,
1654
.trigger = snd_cs46xx_playback_trigger,
1655
.pointer = snd_cs46xx_playback_direct_pointer,
1656
};
1657
1658
static const struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops = {
1659
.open = snd_cs46xx_playback_open_iec958,
1660
.close = snd_cs46xx_playback_close_iec958,
1661
.hw_params = snd_cs46xx_playback_hw_params,
1662
.hw_free = snd_cs46xx_playback_hw_free,
1663
.prepare = snd_cs46xx_playback_prepare,
1664
.trigger = snd_cs46xx_playback_trigger,
1665
.pointer = snd_cs46xx_playback_indirect_pointer,
1666
.ack = snd_cs46xx_playback_transfer,
1667
};
1668
1669
#endif
1670
1671
static const struct snd_pcm_ops snd_cs46xx_playback_ops = {
1672
.open = snd_cs46xx_playback_open,
1673
.close = snd_cs46xx_playback_close,
1674
.hw_params = snd_cs46xx_playback_hw_params,
1675
.hw_free = snd_cs46xx_playback_hw_free,
1676
.prepare = snd_cs46xx_playback_prepare,
1677
.trigger = snd_cs46xx_playback_trigger,
1678
.pointer = snd_cs46xx_playback_direct_pointer,
1679
};
1680
1681
static const struct snd_pcm_ops snd_cs46xx_playback_indirect_ops = {
1682
.open = snd_cs46xx_playback_open,
1683
.close = snd_cs46xx_playback_close,
1684
.hw_params = snd_cs46xx_playback_hw_params,
1685
.hw_free = snd_cs46xx_playback_hw_free,
1686
.prepare = snd_cs46xx_playback_prepare,
1687
.trigger = snd_cs46xx_playback_trigger,
1688
.pointer = snd_cs46xx_playback_indirect_pointer,
1689
.ack = snd_cs46xx_playback_transfer,
1690
};
1691
1692
static const struct snd_pcm_ops snd_cs46xx_capture_ops = {
1693
.open = snd_cs46xx_capture_open,
1694
.close = snd_cs46xx_capture_close,
1695
.hw_params = snd_cs46xx_capture_hw_params,
1696
.hw_free = snd_cs46xx_capture_hw_free,
1697
.prepare = snd_cs46xx_capture_prepare,
1698
.trigger = snd_cs46xx_capture_trigger,
1699
.pointer = snd_cs46xx_capture_direct_pointer,
1700
};
1701
1702
static const struct snd_pcm_ops snd_cs46xx_capture_indirect_ops = {
1703
.open = snd_cs46xx_capture_open,
1704
.close = snd_cs46xx_capture_close,
1705
.hw_params = snd_cs46xx_capture_hw_params,
1706
.hw_free = snd_cs46xx_capture_hw_free,
1707
.prepare = snd_cs46xx_capture_prepare,
1708
.trigger = snd_cs46xx_capture_trigger,
1709
.pointer = snd_cs46xx_capture_indirect_pointer,
1710
.ack = snd_cs46xx_capture_transfer,
1711
};
1712
1713
#ifdef CONFIG_SND_CS46XX_NEW_DSP
1714
#define MAX_PLAYBACK_CHANNELS (DSP_MAX_PCM_CHANNELS - 1)
1715
#else
1716
#define MAX_PLAYBACK_CHANNELS 1
1717
#endif
1718
1719
int snd_cs46xx_pcm(struct snd_cs46xx *chip, int device)
1720
{
1721
struct snd_pcm *pcm;
1722
int err;
1723
1724
err = snd_pcm_new(chip->card, "CS46xx", device, MAX_PLAYBACK_CHANNELS, 1, &pcm);
1725
if (err < 0)
1726
return err;
1727
1728
pcm->private_data = chip;
1729
1730
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_ops);
1731
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cs46xx_capture_ops);
1732
1733
/* global setup */
1734
pcm->info_flags = 0;
1735
strscpy(pcm->name, "CS46xx");
1736
chip->pcm = pcm;
1737
1738
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1739
&chip->pci->dev,
1740
64*1024, 256*1024);
1741
1742
return 0;
1743
}
1744
1745
1746
#ifdef CONFIG_SND_CS46XX_NEW_DSP
1747
int snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device)
1748
{
1749
struct snd_pcm *pcm;
1750
int err;
1751
1752
err = snd_pcm_new(chip->card, "CS46xx - Rear", device, MAX_PLAYBACK_CHANNELS, 0, &pcm);
1753
if (err < 0)
1754
return err;
1755
1756
pcm->private_data = chip;
1757
1758
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_rear_ops);
1759
1760
/* global setup */
1761
pcm->info_flags = 0;
1762
strscpy(pcm->name, "CS46xx - Rear");
1763
chip->pcm_rear = pcm;
1764
1765
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1766
&chip->pci->dev,
1767
64*1024, 256*1024);
1768
1769
return 0;
1770
}
1771
1772
int snd_cs46xx_pcm_center_lfe(struct snd_cs46xx *chip, int device)
1773
{
1774
struct snd_pcm *pcm;
1775
int err;
1776
1777
err = snd_pcm_new(chip->card, "CS46xx - Center LFE", device, MAX_PLAYBACK_CHANNELS, 0, &pcm);
1778
if (err < 0)
1779
return err;
1780
1781
pcm->private_data = chip;
1782
1783
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_clfe_ops);
1784
1785
/* global setup */
1786
pcm->info_flags = 0;
1787
strscpy(pcm->name, "CS46xx - Center LFE");
1788
chip->pcm_center_lfe = pcm;
1789
1790
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1791
&chip->pci->dev,
1792
64*1024, 256*1024);
1793
1794
return 0;
1795
}
1796
1797
int snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device)
1798
{
1799
struct snd_pcm *pcm;
1800
int err;
1801
1802
err = snd_pcm_new(chip->card, "CS46xx - IEC958", device, 1, 0, &pcm);
1803
if (err < 0)
1804
return err;
1805
1806
pcm->private_data = chip;
1807
1808
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_iec958_ops);
1809
1810
/* global setup */
1811
pcm->info_flags = 0;
1812
strscpy(pcm->name, "CS46xx - IEC958");
1813
chip->pcm_iec958 = pcm;
1814
1815
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1816
&chip->pci->dev,
1817
64*1024, 256*1024);
1818
1819
return 0;
1820
}
1821
#endif
1822
1823
/*
1824
* Mixer routines
1825
*/
1826
static void snd_cs46xx_mixer_free_ac97(struct snd_ac97 *ac97)
1827
{
1828
struct snd_cs46xx *chip = ac97->private_data;
1829
1830
if (snd_BUG_ON(ac97 != chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] &&
1831
ac97 != chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]))
1832
return;
1833
1834
if (ac97 == chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]) {
1835
chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] = NULL;
1836
chip->eapd_switch = NULL;
1837
}
1838
else
1839
chip->ac97[CS46XX_SECONDARY_CODEC_INDEX] = NULL;
1840
}
1841
1842
static int snd_cs46xx_vol_info(struct snd_kcontrol *kcontrol,
1843
struct snd_ctl_elem_info *uinfo)
1844
{
1845
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1846
uinfo->count = 2;
1847
uinfo->value.integer.min = 0;
1848
uinfo->value.integer.max = 0x7fff;
1849
return 0;
1850
}
1851
1852
static int snd_cs46xx_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1853
{
1854
struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
1855
int reg = kcontrol->private_value;
1856
unsigned int val = snd_cs46xx_peek(chip, reg);
1857
ucontrol->value.integer.value[0] = 0xffff - (val >> 16);
1858
ucontrol->value.integer.value[1] = 0xffff - (val & 0xffff);
1859
return 0;
1860
}
1861
1862
static int snd_cs46xx_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1863
{
1864
struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
1865
int reg = kcontrol->private_value;
1866
unsigned int val = ((0xffff - ucontrol->value.integer.value[0]) << 16 |
1867
(0xffff - ucontrol->value.integer.value[1]));
1868
unsigned int old = snd_cs46xx_peek(chip, reg);
1869
int change = (old != val);
1870
1871
if (change) {
1872
snd_cs46xx_poke(chip, reg, val);
1873
}
1874
1875
return change;
1876
}
1877
1878
#ifdef CONFIG_SND_CS46XX_NEW_DSP
1879
1880
static int snd_cs46xx_vol_dac_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1881
{
1882
struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
1883
1884
ucontrol->value.integer.value[0] = chip->dsp_spos_instance->dac_volume_left;
1885
ucontrol->value.integer.value[1] = chip->dsp_spos_instance->dac_volume_right;
1886
1887
return 0;
1888
}
1889
1890
static int snd_cs46xx_vol_dac_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1891
{
1892
struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
1893
int change = 0;
1894
1895
if (chip->dsp_spos_instance->dac_volume_right != ucontrol->value.integer.value[0] ||
1896
chip->dsp_spos_instance->dac_volume_left != ucontrol->value.integer.value[1]) {
1897
cs46xx_dsp_set_dac_volume(chip,
1898
ucontrol->value.integer.value[0],
1899
ucontrol->value.integer.value[1]);
1900
change = 1;
1901
}
1902
1903
return change;
1904
}
1905
1906
#if 0
1907
static int snd_cs46xx_vol_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1908
{
1909
struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
1910
1911
ucontrol->value.integer.value[0] = chip->dsp_spos_instance->spdif_input_volume_left;
1912
ucontrol->value.integer.value[1] = chip->dsp_spos_instance->spdif_input_volume_right;
1913
return 0;
1914
}
1915
1916
static int snd_cs46xx_vol_iec958_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1917
{
1918
struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
1919
int change = 0;
1920
1921
if (chip->dsp_spos_instance->spdif_input_volume_left != ucontrol->value.integer.value[0] ||
1922
chip->dsp_spos_instance->spdif_input_volume_right!= ucontrol->value.integer.value[1]) {
1923
cs46xx_dsp_set_iec958_volume (chip,
1924
ucontrol->value.integer.value[0],
1925
ucontrol->value.integer.value[1]);
1926
change = 1;
1927
}
1928
1929
return change;
1930
}
1931
#endif
1932
1933
#define snd_mixer_boolean_info snd_ctl_boolean_mono_info
1934
1935
static int snd_cs46xx_iec958_get(struct snd_kcontrol *kcontrol,
1936
struct snd_ctl_elem_value *ucontrol)
1937
{
1938
struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
1939
int reg = kcontrol->private_value;
1940
1941
if (reg == CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT)
1942
ucontrol->value.integer.value[0] = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED);
1943
else
1944
ucontrol->value.integer.value[0] = chip->dsp_spos_instance->spdif_status_in;
1945
1946
return 0;
1947
}
1948
1949
static int snd_cs46xx_iec958_put(struct snd_kcontrol *kcontrol,
1950
struct snd_ctl_elem_value *ucontrol)
1951
{
1952
struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
1953
int change, res;
1954
1955
switch (kcontrol->private_value) {
1956
case CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT:
1957
scoped_guard(mutex, &chip->spos_mutex) {
1958
change = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED);
1959
if (ucontrol->value.integer.value[0] && !change)
1960
cs46xx_dsp_enable_spdif_out(chip);
1961
else if (change && !ucontrol->value.integer.value[0])
1962
cs46xx_dsp_disable_spdif_out(chip);
1963
1964
res = (change != (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED));
1965
}
1966
break;
1967
case CS46XX_MIXER_SPDIF_INPUT_ELEMENT:
1968
change = chip->dsp_spos_instance->spdif_status_in;
1969
if (ucontrol->value.integer.value[0] && !change) {
1970
cs46xx_dsp_enable_spdif_in(chip);
1971
/* restore volume */
1972
}
1973
else if (change && !ucontrol->value.integer.value[0])
1974
cs46xx_dsp_disable_spdif_in(chip);
1975
1976
res = (change != chip->dsp_spos_instance->spdif_status_in);
1977
break;
1978
default:
1979
res = -EINVAL;
1980
snd_BUG(); /* should never happen ... */
1981
}
1982
1983
return res;
1984
}
1985
1986
static int snd_cs46xx_adc_capture_get(struct snd_kcontrol *kcontrol,
1987
struct snd_ctl_elem_value *ucontrol)
1988
{
1989
struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
1990
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
1991
1992
if (ins->adc_input != NULL)
1993
ucontrol->value.integer.value[0] = 1;
1994
else
1995
ucontrol->value.integer.value[0] = 0;
1996
1997
return 0;
1998
}
1999
2000
static int snd_cs46xx_adc_capture_put(struct snd_kcontrol *kcontrol,
2001
struct snd_ctl_elem_value *ucontrol)
2002
{
2003
struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2004
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
2005
int change = 0;
2006
2007
if (ucontrol->value.integer.value[0] && !ins->adc_input) {
2008
cs46xx_dsp_enable_adc_capture(chip);
2009
change = 1;
2010
} else if (!ucontrol->value.integer.value[0] && ins->adc_input) {
2011
cs46xx_dsp_disable_adc_capture(chip);
2012
change = 1;
2013
}
2014
return change;
2015
}
2016
2017
static int snd_cs46xx_pcm_capture_get(struct snd_kcontrol *kcontrol,
2018
struct snd_ctl_elem_value *ucontrol)
2019
{
2020
struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2021
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
2022
2023
if (ins->pcm_input != NULL)
2024
ucontrol->value.integer.value[0] = 1;
2025
else
2026
ucontrol->value.integer.value[0] = 0;
2027
2028
return 0;
2029
}
2030
2031
2032
static int snd_cs46xx_pcm_capture_put(struct snd_kcontrol *kcontrol,
2033
struct snd_ctl_elem_value *ucontrol)
2034
{
2035
struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2036
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
2037
int change = 0;
2038
2039
if (ucontrol->value.integer.value[0] && !ins->pcm_input) {
2040
cs46xx_dsp_enable_pcm_capture(chip);
2041
change = 1;
2042
} else if (!ucontrol->value.integer.value[0] && ins->pcm_input) {
2043
cs46xx_dsp_disable_pcm_capture(chip);
2044
change = 1;
2045
}
2046
2047
return change;
2048
}
2049
2050
static int snd_herc_spdif_select_get(struct snd_kcontrol *kcontrol,
2051
struct snd_ctl_elem_value *ucontrol)
2052
{
2053
struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2054
2055
int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR);
2056
2057
if (val1 & EGPIODR_GPOE0)
2058
ucontrol->value.integer.value[0] = 1;
2059
else
2060
ucontrol->value.integer.value[0] = 0;
2061
2062
return 0;
2063
}
2064
2065
/*
2066
* Game Theatre XP card - EGPIO[0] is used to select SPDIF input optical or coaxial.
2067
*/
2068
static int snd_herc_spdif_select_put(struct snd_kcontrol *kcontrol,
2069
struct snd_ctl_elem_value *ucontrol)
2070
{
2071
struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2072
int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR);
2073
int val2 = snd_cs46xx_peekBA0(chip, BA0_EGPIOPTR);
2074
2075
if (ucontrol->value.integer.value[0]) {
2076
/* optical is default */
2077
snd_cs46xx_pokeBA0(chip, BA0_EGPIODR,
2078
EGPIODR_GPOE0 | val1); /* enable EGPIO0 output */
2079
snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR,
2080
EGPIOPTR_GPPT0 | val2); /* open-drain on output */
2081
} else {
2082
/* coaxial */
2083
snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, val1 & ~EGPIODR_GPOE0); /* disable */
2084
snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, val2 & ~EGPIOPTR_GPPT0); /* disable */
2085
}
2086
2087
/* checking diff from the EGPIO direction register
2088
should be enough */
2089
return (val1 != (int)snd_cs46xx_peekBA0(chip, BA0_EGPIODR));
2090
}
2091
2092
2093
static int snd_cs46xx_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
2094
{
2095
uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
2096
uinfo->count = 1;
2097
return 0;
2098
}
2099
2100
static int snd_cs46xx_spdif_default_get(struct snd_kcontrol *kcontrol,
2101
struct snd_ctl_elem_value *ucontrol)
2102
{
2103
struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2104
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
2105
2106
guard(mutex)(&chip->spos_mutex);
2107
ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_default >> 24) & 0xff);
2108
ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_default >> 16) & 0xff);
2109
ucontrol->value.iec958.status[2] = 0;
2110
ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_default) & 0xff);
2111
2112
return 0;
2113
}
2114
2115
static int snd_cs46xx_spdif_default_put(struct snd_kcontrol *kcontrol,
2116
struct snd_ctl_elem_value *ucontrol)
2117
{
2118
struct snd_cs46xx * chip = snd_kcontrol_chip(kcontrol);
2119
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
2120
unsigned int val;
2121
int change;
2122
2123
guard(mutex)(&chip->spos_mutex);
2124
val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) |
2125
((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[2]) << 16) |
2126
((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3])) |
2127
/* left and right validity bit */
2128
(1 << 13) | (1 << 12);
2129
2130
2131
change = (unsigned int)ins->spdif_csuv_default != val;
2132
ins->spdif_csuv_default = val;
2133
2134
if ( !(ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) )
2135
cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val);
2136
2137
return change;
2138
}
2139
2140
static int snd_cs46xx_spdif_mask_get(struct snd_kcontrol *kcontrol,
2141
struct snd_ctl_elem_value *ucontrol)
2142
{
2143
ucontrol->value.iec958.status[0] = 0xff;
2144
ucontrol->value.iec958.status[1] = 0xff;
2145
ucontrol->value.iec958.status[2] = 0x00;
2146
ucontrol->value.iec958.status[3] = 0xff;
2147
return 0;
2148
}
2149
2150
static int snd_cs46xx_spdif_stream_get(struct snd_kcontrol *kcontrol,
2151
struct snd_ctl_elem_value *ucontrol)
2152
{
2153
struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2154
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
2155
2156
guard(mutex)(&chip->spos_mutex);
2157
ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_stream >> 24) & 0xff);
2158
ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_stream >> 16) & 0xff);
2159
ucontrol->value.iec958.status[2] = 0;
2160
ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_stream) & 0xff);
2161
2162
return 0;
2163
}
2164
2165
static int snd_cs46xx_spdif_stream_put(struct snd_kcontrol *kcontrol,
2166
struct snd_ctl_elem_value *ucontrol)
2167
{
2168
struct snd_cs46xx * chip = snd_kcontrol_chip(kcontrol);
2169
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
2170
unsigned int val;
2171
int change;
2172
2173
guard(mutex)(&chip->spos_mutex);
2174
val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) |
2175
((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[1]) << 16) |
2176
((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3])) |
2177
/* left and right validity bit */
2178
(1 << 13) | (1 << 12);
2179
2180
2181
change = ins->spdif_csuv_stream != val;
2182
ins->spdif_csuv_stream = val;
2183
2184
if ( ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN )
2185
cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val);
2186
2187
return change;
2188
}
2189
2190
#endif /* CONFIG_SND_CS46XX_NEW_DSP */
2191
2192
2193
static const struct snd_kcontrol_new snd_cs46xx_controls[] = {
2194
{
2195
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2196
.name = "DAC Volume",
2197
.info = snd_cs46xx_vol_info,
2198
#ifndef CONFIG_SND_CS46XX_NEW_DSP
2199
.get = snd_cs46xx_vol_get,
2200
.put = snd_cs46xx_vol_put,
2201
.private_value = BA1_PVOL,
2202
#else
2203
.get = snd_cs46xx_vol_dac_get,
2204
.put = snd_cs46xx_vol_dac_put,
2205
#endif
2206
},
2207
2208
{
2209
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2210
.name = "ADC Volume",
2211
.info = snd_cs46xx_vol_info,
2212
.get = snd_cs46xx_vol_get,
2213
.put = snd_cs46xx_vol_put,
2214
#ifndef CONFIG_SND_CS46XX_NEW_DSP
2215
.private_value = BA1_CVOL,
2216
#else
2217
.private_value = (VARIDECIMATE_SCB_ADDR + 0xE) << 2,
2218
#endif
2219
},
2220
#ifdef CONFIG_SND_CS46XX_NEW_DSP
2221
{
2222
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2223
.name = "ADC Capture Switch",
2224
.info = snd_mixer_boolean_info,
2225
.get = snd_cs46xx_adc_capture_get,
2226
.put = snd_cs46xx_adc_capture_put
2227
},
2228
{
2229
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2230
.name = "DAC Capture Switch",
2231
.info = snd_mixer_boolean_info,
2232
.get = snd_cs46xx_pcm_capture_get,
2233
.put = snd_cs46xx_pcm_capture_put
2234
},
2235
{
2236
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2237
.name = SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH),
2238
.info = snd_mixer_boolean_info,
2239
.get = snd_cs46xx_iec958_get,
2240
.put = snd_cs46xx_iec958_put,
2241
.private_value = CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT,
2242
},
2243
{
2244
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2245
.name = SNDRV_CTL_NAME_IEC958("Input ",NONE,SWITCH),
2246
.info = snd_mixer_boolean_info,
2247
.get = snd_cs46xx_iec958_get,
2248
.put = snd_cs46xx_iec958_put,
2249
.private_value = CS46XX_MIXER_SPDIF_INPUT_ELEMENT,
2250
},
2251
#if 0
2252
/* Input IEC958 volume does not work for the moment. (Benny) */
2253
{
2254
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2255
.name = SNDRV_CTL_NAME_IEC958("Input ",NONE,VOLUME),
2256
.info = snd_cs46xx_vol_info,
2257
.get = snd_cs46xx_vol_iec958_get,
2258
.put = snd_cs46xx_vol_iec958_put,
2259
.private_value = (ASYNCRX_SCB_ADDR + 0xE) << 2,
2260
},
2261
#endif
2262
{
2263
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
2264
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
2265
.info = snd_cs46xx_spdif_info,
2266
.get = snd_cs46xx_spdif_default_get,
2267
.put = snd_cs46xx_spdif_default_put,
2268
},
2269
{
2270
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
2271
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
2272
.info = snd_cs46xx_spdif_info,
2273
.get = snd_cs46xx_spdif_mask_get,
2274
.access = SNDRV_CTL_ELEM_ACCESS_READ
2275
},
2276
{
2277
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
2278
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
2279
.info = snd_cs46xx_spdif_info,
2280
.get = snd_cs46xx_spdif_stream_get,
2281
.put = snd_cs46xx_spdif_stream_put
2282
},
2283
2284
#endif
2285
};
2286
2287
#ifdef CONFIG_SND_CS46XX_NEW_DSP
2288
/* set primary cs4294 codec into Extended Audio Mode */
2289
static int snd_cs46xx_front_dup_get(struct snd_kcontrol *kcontrol,
2290
struct snd_ctl_elem_value *ucontrol)
2291
{
2292
struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2293
unsigned short val;
2294
val = snd_ac97_read(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX], AC97_CSR_ACMODE);
2295
ucontrol->value.integer.value[0] = (val & 0x200) ? 0 : 1;
2296
return 0;
2297
}
2298
2299
static int snd_cs46xx_front_dup_put(struct snd_kcontrol *kcontrol,
2300
struct snd_ctl_elem_value *ucontrol)
2301
{
2302
struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
2303
return snd_ac97_update_bits(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX],
2304
AC97_CSR_ACMODE, 0x200,
2305
ucontrol->value.integer.value[0] ? 0 : 0x200);
2306
}
2307
2308
static const struct snd_kcontrol_new snd_cs46xx_front_dup_ctl = {
2309
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2310
.name = "Duplicate Front",
2311
.info = snd_mixer_boolean_info,
2312
.get = snd_cs46xx_front_dup_get,
2313
.put = snd_cs46xx_front_dup_put,
2314
};
2315
#endif
2316
2317
#ifdef CONFIG_SND_CS46XX_NEW_DSP
2318
/* Only available on the Hercules Game Theater XP soundcard */
2319
static const struct snd_kcontrol_new snd_hercules_controls[] = {
2320
{
2321
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2322
.name = "Optical/Coaxial SPDIF Input Switch",
2323
.info = snd_mixer_boolean_info,
2324
.get = snd_herc_spdif_select_get,
2325
.put = snd_herc_spdif_select_put,
2326
},
2327
};
2328
2329
2330
static void snd_cs46xx_codec_reset (struct snd_ac97 * ac97)
2331
{
2332
unsigned long end_time;
2333
int err;
2334
2335
/* reset to defaults */
2336
snd_ac97_write(ac97, AC97_RESET, 0);
2337
2338
/* set the desired CODEC mode */
2339
if (ac97->num == CS46XX_PRIMARY_CODEC_INDEX) {
2340
dev_dbg(ac97->bus->card->dev, "CODEC1 mode %04x\n", 0x0);
2341
snd_cs46xx_ac97_write(ac97, AC97_CSR_ACMODE, 0x0);
2342
} else if (ac97->num == CS46XX_SECONDARY_CODEC_INDEX) {
2343
dev_dbg(ac97->bus->card->dev, "CODEC2 mode %04x\n", 0x3);
2344
snd_cs46xx_ac97_write(ac97, AC97_CSR_ACMODE, 0x3);
2345
} else {
2346
snd_BUG(); /* should never happen ... */
2347
}
2348
2349
udelay(50);
2350
2351
/* it's necessary to wait awhile until registers are accessible after RESET */
2352
/* because the PCM or MASTER volume registers can be modified, */
2353
/* the REC_GAIN register is used for tests */
2354
end_time = jiffies + HZ;
2355
do {
2356
unsigned short ext_mid;
2357
2358
/* use preliminary reads to settle the communication */
2359
snd_ac97_read(ac97, AC97_RESET);
2360
snd_ac97_read(ac97, AC97_VENDOR_ID1);
2361
snd_ac97_read(ac97, AC97_VENDOR_ID2);
2362
/* modem? */
2363
ext_mid = snd_ac97_read(ac97, AC97_EXTENDED_MID);
2364
if (ext_mid != 0xffff && (ext_mid & 1) != 0)
2365
return;
2366
2367
/* test if we can write to the record gain volume register */
2368
snd_ac97_write(ac97, AC97_REC_GAIN, 0x8a05);
2369
err = snd_ac97_read(ac97, AC97_REC_GAIN);
2370
if (err == 0x8a05)
2371
return;
2372
2373
msleep(10);
2374
} while (time_after_eq(end_time, jiffies));
2375
2376
dev_err(ac97->bus->card->dev,
2377
"CS46xx secondary codec doesn't respond!\n");
2378
}
2379
#endif
2380
2381
static int cs46xx_detect_codec(struct snd_cs46xx *chip, int codec)
2382
{
2383
int idx, err;
2384
struct snd_ac97_template ac97;
2385
2386
memset(&ac97, 0, sizeof(ac97));
2387
ac97.private_data = chip;
2388
ac97.private_free = snd_cs46xx_mixer_free_ac97;
2389
ac97.num = codec;
2390
if (chip->amplifier_ctrl == amp_voyetra)
2391
ac97.scaps = AC97_SCAP_INV_EAPD;
2392
2393
if (codec == CS46XX_SECONDARY_CODEC_INDEX) {
2394
snd_cs46xx_codec_write(chip, AC97_RESET, 0, codec);
2395
udelay(10);
2396
if (snd_cs46xx_codec_read(chip, AC97_RESET, codec) & 0x8000) {
2397
dev_dbg(chip->card->dev,
2398
"secondary codec not present\n");
2399
return -ENXIO;
2400
}
2401
}
2402
2403
snd_cs46xx_codec_write(chip, AC97_MASTER, 0x8000, codec);
2404
for (idx = 0; idx < 100; ++idx) {
2405
if (snd_cs46xx_codec_read(chip, AC97_MASTER, codec) == 0x8000) {
2406
err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97[codec]);
2407
return err;
2408
}
2409
msleep(10);
2410
}
2411
dev_dbg(chip->card->dev, "codec %d detection timeout\n", codec);
2412
return -ENXIO;
2413
}
2414
2415
int snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device)
2416
{
2417
struct snd_card *card = chip->card;
2418
int err;
2419
unsigned int idx;
2420
static const struct snd_ac97_bus_ops ops = {
2421
#ifdef CONFIG_SND_CS46XX_NEW_DSP
2422
.reset = snd_cs46xx_codec_reset,
2423
#endif
2424
.write = snd_cs46xx_ac97_write,
2425
.read = snd_cs46xx_ac97_read,
2426
};
2427
2428
/* detect primary codec */
2429
chip->nr_ac97_codecs = 0;
2430
dev_dbg(chip->card->dev, "detecting primary codec\n");
2431
err = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus);
2432
if (err < 0)
2433
return err;
2434
2435
if (cs46xx_detect_codec(chip, CS46XX_PRIMARY_CODEC_INDEX) < 0)
2436
return -ENXIO;
2437
chip->nr_ac97_codecs = 1;
2438
2439
#ifdef CONFIG_SND_CS46XX_NEW_DSP
2440
dev_dbg(chip->card->dev, "detecting secondary codec\n");
2441
/* try detect a secondary codec */
2442
if (! cs46xx_detect_codec(chip, CS46XX_SECONDARY_CODEC_INDEX))
2443
chip->nr_ac97_codecs = 2;
2444
#endif /* CONFIG_SND_CS46XX_NEW_DSP */
2445
2446
/* add cs4630 mixer controls */
2447
for (idx = 0; idx < ARRAY_SIZE(snd_cs46xx_controls); idx++) {
2448
struct snd_kcontrol *kctl;
2449
kctl = snd_ctl_new1(&snd_cs46xx_controls[idx], chip);
2450
if (kctl && kctl->id.iface == SNDRV_CTL_ELEM_IFACE_PCM)
2451
kctl->id.device = spdif_device;
2452
err = snd_ctl_add(card, kctl);
2453
if (err < 0)
2454
return err;
2455
}
2456
2457
/* get EAPD mixer switch (for voyetra hack) */
2458
chip->eapd_switch = snd_ctl_find_id_mixer(chip->card,
2459
"External Amplifier");
2460
2461
#ifdef CONFIG_SND_CS46XX_NEW_DSP
2462
if (chip->nr_ac97_codecs == 1) {
2463
unsigned int id2 = chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]->id & 0xffff;
2464
if ((id2 & 0xfff0) == 0x5920) { /* CS4294 and CS4298 */
2465
err = snd_ctl_add(card, snd_ctl_new1(&snd_cs46xx_front_dup_ctl, chip));
2466
if (err < 0)
2467
return err;
2468
snd_ac97_write_cache(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX],
2469
AC97_CSR_ACMODE, 0x200);
2470
}
2471
}
2472
/* do soundcard specific mixer setup */
2473
if (chip->mixer_init) {
2474
dev_dbg(chip->card->dev, "calling chip->mixer_init(chip);\n");
2475
chip->mixer_init(chip);
2476
}
2477
#endif
2478
2479
/* turn on amplifier */
2480
chip->amplifier_ctrl(chip, 1);
2481
2482
return 0;
2483
}
2484
2485
/*
2486
* RawMIDI interface
2487
*/
2488
2489
static void snd_cs46xx_midi_reset(struct snd_cs46xx *chip)
2490
{
2491
snd_cs46xx_pokeBA0(chip, BA0_MIDCR, MIDCR_MRST);
2492
udelay(100);
2493
snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2494
}
2495
2496
static int snd_cs46xx_midi_input_open(struct snd_rawmidi_substream *substream)
2497
{
2498
struct snd_cs46xx *chip = substream->rmidi->private_data;
2499
2500
chip->active_ctrl(chip, 1);
2501
guard(spinlock_irq)(&chip->reg_lock);
2502
chip->uartm |= CS46XX_MODE_INPUT;
2503
chip->midcr |= MIDCR_RXE;
2504
chip->midi_input = substream;
2505
if (!(chip->uartm & CS46XX_MODE_OUTPUT)) {
2506
snd_cs46xx_midi_reset(chip);
2507
} else {
2508
snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2509
}
2510
return 0;
2511
}
2512
2513
static int snd_cs46xx_midi_input_close(struct snd_rawmidi_substream *substream)
2514
{
2515
struct snd_cs46xx *chip = substream->rmidi->private_data;
2516
2517
scoped_guard(spinlock_irq, &chip->reg_lock) {
2518
chip->midcr &= ~(MIDCR_RXE | MIDCR_RIE);
2519
chip->midi_input = NULL;
2520
if (!(chip->uartm & CS46XX_MODE_OUTPUT)) {
2521
snd_cs46xx_midi_reset(chip);
2522
} else {
2523
snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2524
}
2525
chip->uartm &= ~CS46XX_MODE_INPUT;
2526
}
2527
chip->active_ctrl(chip, -1);
2528
return 0;
2529
}
2530
2531
static int snd_cs46xx_midi_output_open(struct snd_rawmidi_substream *substream)
2532
{
2533
struct snd_cs46xx *chip = substream->rmidi->private_data;
2534
2535
chip->active_ctrl(chip, 1);
2536
2537
guard(spinlock_irq)(&chip->reg_lock);
2538
chip->uartm |= CS46XX_MODE_OUTPUT;
2539
chip->midcr |= MIDCR_TXE;
2540
chip->midi_output = substream;
2541
if (!(chip->uartm & CS46XX_MODE_INPUT)) {
2542
snd_cs46xx_midi_reset(chip);
2543
} else {
2544
snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2545
}
2546
return 0;
2547
}
2548
2549
static int snd_cs46xx_midi_output_close(struct snd_rawmidi_substream *substream)
2550
{
2551
struct snd_cs46xx *chip = substream->rmidi->private_data;
2552
2553
scoped_guard(spinlock_irq, &chip->reg_lock) {
2554
chip->midcr &= ~(MIDCR_TXE | MIDCR_TIE);
2555
chip->midi_output = NULL;
2556
if (!(chip->uartm & CS46XX_MODE_INPUT)) {
2557
snd_cs46xx_midi_reset(chip);
2558
} else {
2559
snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2560
}
2561
chip->uartm &= ~CS46XX_MODE_OUTPUT;
2562
}
2563
chip->active_ctrl(chip, -1);
2564
return 0;
2565
}
2566
2567
static void snd_cs46xx_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
2568
{
2569
struct snd_cs46xx *chip = substream->rmidi->private_data;
2570
2571
guard(spinlock_irqsave)(&chip->reg_lock);
2572
if (up) {
2573
if ((chip->midcr & MIDCR_RIE) == 0) {
2574
chip->midcr |= MIDCR_RIE;
2575
snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2576
}
2577
} else {
2578
if (chip->midcr & MIDCR_RIE) {
2579
chip->midcr &= ~MIDCR_RIE;
2580
snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2581
}
2582
}
2583
}
2584
2585
static void snd_cs46xx_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
2586
{
2587
struct snd_cs46xx *chip = substream->rmidi->private_data;
2588
unsigned char byte;
2589
2590
guard(spinlock_irqsave)(&chip->reg_lock);
2591
if (up) {
2592
if ((chip->midcr & MIDCR_TIE) == 0) {
2593
chip->midcr |= MIDCR_TIE;
2594
/* fill UART FIFO buffer at first, and turn Tx interrupts only if necessary */
2595
while ((chip->midcr & MIDCR_TIE) &&
2596
(snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_TBF) == 0) {
2597
if (snd_rawmidi_transmit(substream, &byte, 1) != 1) {
2598
chip->midcr &= ~MIDCR_TIE;
2599
} else {
2600
snd_cs46xx_pokeBA0(chip, BA0_MIDWP, byte);
2601
}
2602
}
2603
snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2604
}
2605
} else {
2606
if (chip->midcr & MIDCR_TIE) {
2607
chip->midcr &= ~MIDCR_TIE;
2608
snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
2609
}
2610
}
2611
}
2612
2613
static const struct snd_rawmidi_ops snd_cs46xx_midi_output =
2614
{
2615
.open = snd_cs46xx_midi_output_open,
2616
.close = snd_cs46xx_midi_output_close,
2617
.trigger = snd_cs46xx_midi_output_trigger,
2618
};
2619
2620
static const struct snd_rawmidi_ops snd_cs46xx_midi_input =
2621
{
2622
.open = snd_cs46xx_midi_input_open,
2623
.close = snd_cs46xx_midi_input_close,
2624
.trigger = snd_cs46xx_midi_input_trigger,
2625
};
2626
2627
int snd_cs46xx_midi(struct snd_cs46xx *chip, int device)
2628
{
2629
struct snd_rawmidi *rmidi;
2630
int err;
2631
2632
err = snd_rawmidi_new(chip->card, "CS46XX", device, 1, 1, &rmidi);
2633
if (err < 0)
2634
return err;
2635
strscpy(rmidi->name, "CS46XX");
2636
snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_cs46xx_midi_output);
2637
snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_cs46xx_midi_input);
2638
rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX;
2639
rmidi->private_data = chip;
2640
chip->rmidi = rmidi;
2641
return 0;
2642
}
2643
2644
2645
/*
2646
* gameport interface
2647
*/
2648
2649
#if IS_REACHABLE(CONFIG_GAMEPORT)
2650
2651
static void snd_cs46xx_gameport_trigger(struct gameport *gameport)
2652
{
2653
struct snd_cs46xx *chip = gameport_get_port_data(gameport);
2654
2655
if (snd_BUG_ON(!chip))
2656
return;
2657
snd_cs46xx_pokeBA0(chip, BA0_JSPT, 0xFF); //outb(gameport->io, 0xFF);
2658
}
2659
2660
static unsigned char snd_cs46xx_gameport_read(struct gameport *gameport)
2661
{
2662
struct snd_cs46xx *chip = gameport_get_port_data(gameport);
2663
2664
if (snd_BUG_ON(!chip))
2665
return 0;
2666
return snd_cs46xx_peekBA0(chip, BA0_JSPT); //inb(gameport->io);
2667
}
2668
2669
static int snd_cs46xx_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons)
2670
{
2671
struct snd_cs46xx *chip = gameport_get_port_data(gameport);
2672
unsigned js1, js2, jst;
2673
2674
if (snd_BUG_ON(!chip))
2675
return 0;
2676
2677
js1 = snd_cs46xx_peekBA0(chip, BA0_JSC1);
2678
js2 = snd_cs46xx_peekBA0(chip, BA0_JSC2);
2679
jst = snd_cs46xx_peekBA0(chip, BA0_JSPT);
2680
2681
*buttons = (~jst >> 4) & 0x0F;
2682
2683
axes[0] = ((js1 & JSC1_Y1V_MASK) >> JSC1_Y1V_SHIFT) & 0xFFFF;
2684
axes[1] = ((js1 & JSC1_X1V_MASK) >> JSC1_X1V_SHIFT) & 0xFFFF;
2685
axes[2] = ((js2 & JSC2_Y2V_MASK) >> JSC2_Y2V_SHIFT) & 0xFFFF;
2686
axes[3] = ((js2 & JSC2_X2V_MASK) >> JSC2_X2V_SHIFT) & 0xFFFF;
2687
2688
for(jst=0;jst<4;++jst)
2689
if(axes[jst]==0xFFFF) axes[jst] = -1;
2690
return 0;
2691
}
2692
2693
static int snd_cs46xx_gameport_open(struct gameport *gameport, int mode)
2694
{
2695
switch (mode) {
2696
case GAMEPORT_MODE_COOKED:
2697
return 0;
2698
case GAMEPORT_MODE_RAW:
2699
return 0;
2700
default:
2701
return -1;
2702
}
2703
return 0;
2704
}
2705
2706
int snd_cs46xx_gameport(struct snd_cs46xx *chip)
2707
{
2708
struct gameport *gp;
2709
2710
chip->gameport = gp = gameport_allocate_port();
2711
if (!gp) {
2712
dev_err(chip->card->dev,
2713
"cannot allocate memory for gameport\n");
2714
return -ENOMEM;
2715
}
2716
2717
gameport_set_name(gp, "CS46xx Gameport");
2718
gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
2719
gameport_set_dev_parent(gp, &chip->pci->dev);
2720
gameport_set_port_data(gp, chip);
2721
2722
gp->open = snd_cs46xx_gameport_open;
2723
gp->read = snd_cs46xx_gameport_read;
2724
gp->trigger = snd_cs46xx_gameport_trigger;
2725
gp->cooked_read = snd_cs46xx_gameport_cooked_read;
2726
2727
snd_cs46xx_pokeBA0(chip, BA0_JSIO, 0xFF); // ?
2728
snd_cs46xx_pokeBA0(chip, BA0_JSCTL, JSCTL_SP_MEDIUM_SLOW);
2729
2730
gameport_register_port(gp);
2731
2732
return 0;
2733
}
2734
2735
static inline void snd_cs46xx_remove_gameport(struct snd_cs46xx *chip)
2736
{
2737
if (chip->gameport) {
2738
gameport_unregister_port(chip->gameport);
2739
chip->gameport = NULL;
2740
}
2741
}
2742
#else
2743
int snd_cs46xx_gameport(struct snd_cs46xx *chip) { return -ENOSYS; }
2744
static inline void snd_cs46xx_remove_gameport(struct snd_cs46xx *chip) { }
2745
#endif /* CONFIG_GAMEPORT */
2746
2747
#ifdef CONFIG_SND_PROC_FS
2748
/*
2749
* proc interface
2750
*/
2751
2752
static ssize_t snd_cs46xx_io_read(struct snd_info_entry *entry,
2753
void *file_private_data,
2754
struct file *file, char __user *buf,
2755
size_t count, loff_t pos)
2756
{
2757
struct snd_cs46xx_region *region = entry->private_data;
2758
2759
if (copy_to_user_fromio(buf, region->remap_addr + pos, count))
2760
return -EFAULT;
2761
return count;
2762
}
2763
2764
static const struct snd_info_entry_ops snd_cs46xx_proc_io_ops = {
2765
.read = snd_cs46xx_io_read,
2766
};
2767
2768
static int snd_cs46xx_proc_init(struct snd_card *card, struct snd_cs46xx *chip)
2769
{
2770
struct snd_info_entry *entry;
2771
int idx;
2772
2773
for (idx = 0; idx < 5; idx++) {
2774
struct snd_cs46xx_region *region = &chip->region.idx[idx];
2775
if (! snd_card_proc_new(card, region->name, &entry)) {
2776
entry->content = SNDRV_INFO_CONTENT_DATA;
2777
entry->private_data = chip;
2778
entry->c.ops = &snd_cs46xx_proc_io_ops;
2779
entry->size = region->size;
2780
entry->mode = S_IFREG | 0400;
2781
}
2782
}
2783
#ifdef CONFIG_SND_CS46XX_NEW_DSP
2784
cs46xx_dsp_proc_init(card, chip);
2785
#endif
2786
return 0;
2787
}
2788
2789
static int snd_cs46xx_proc_done(struct snd_cs46xx *chip)
2790
{
2791
#ifdef CONFIG_SND_CS46XX_NEW_DSP
2792
cs46xx_dsp_proc_done(chip);
2793
#endif
2794
return 0;
2795
}
2796
#else /* !CONFIG_SND_PROC_FS */
2797
#define snd_cs46xx_proc_init(card, chip)
2798
#define snd_cs46xx_proc_done(chip)
2799
#endif
2800
2801
/*
2802
* stop the h/w
2803
*/
2804
static void snd_cs46xx_hw_stop(struct snd_cs46xx *chip)
2805
{
2806
unsigned int tmp;
2807
2808
tmp = snd_cs46xx_peek(chip, BA1_PFIE);
2809
tmp &= ~0x0000f03f;
2810
tmp |= 0x00000010;
2811
snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt disable */
2812
2813
tmp = snd_cs46xx_peek(chip, BA1_CIE);
2814
tmp &= ~0x0000003f;
2815
tmp |= 0x00000011;
2816
snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt disable */
2817
2818
/*
2819
* Stop playback DMA.
2820
*/
2821
tmp = snd_cs46xx_peek(chip, BA1_PCTL);
2822
snd_cs46xx_poke(chip, BA1_PCTL, tmp & 0x0000ffff);
2823
2824
/*
2825
* Stop capture DMA.
2826
*/
2827
tmp = snd_cs46xx_peek(chip, BA1_CCTL);
2828
snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000);
2829
2830
/*
2831
* Reset the processor.
2832
*/
2833
snd_cs46xx_reset(chip);
2834
2835
snd_cs46xx_proc_stop(chip);
2836
2837
/*
2838
* Power down the PLL.
2839
*/
2840
snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, 0);
2841
2842
/*
2843
* Turn off the Processor by turning off the software clock enable flag in
2844
* the clock control register.
2845
*/
2846
tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1) & ~CLKCR1_SWCE;
2847
snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp);
2848
}
2849
2850
2851
static void snd_cs46xx_free(struct snd_card *card)
2852
{
2853
struct snd_cs46xx *chip = card->private_data;
2854
#ifdef CONFIG_SND_CS46XX_NEW_DSP
2855
int idx;
2856
#endif
2857
2858
if (chip->active_ctrl)
2859
chip->active_ctrl(chip, 1);
2860
2861
snd_cs46xx_remove_gameport(chip);
2862
2863
if (chip->amplifier_ctrl)
2864
chip->amplifier_ctrl(chip, -chip->amplifier); /* force to off */
2865
2866
snd_cs46xx_proc_done(chip);
2867
2868
snd_cs46xx_hw_stop(chip);
2869
2870
if (chip->active_ctrl)
2871
chip->active_ctrl(chip, -chip->amplifier);
2872
2873
#ifdef CONFIG_SND_CS46XX_NEW_DSP
2874
if (chip->dsp_spos_instance) {
2875
cs46xx_dsp_spos_destroy(chip);
2876
chip->dsp_spos_instance = NULL;
2877
}
2878
for (idx = 0; idx < CS46XX_DSP_MODULES; idx++)
2879
free_module_desc(chip->modules[idx]);
2880
#else
2881
vfree(chip->ba1);
2882
#endif
2883
}
2884
2885
/*
2886
* initialize chip
2887
*/
2888
static int snd_cs46xx_chip_init(struct snd_cs46xx *chip)
2889
{
2890
int timeout;
2891
2892
/*
2893
* First, blast the clock control register to zero so that the PLL starts
2894
* out in a known state, and blast the master serial port control register
2895
* to zero so that the serial ports also start out in a known state.
2896
*/
2897
snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, 0);
2898
snd_cs46xx_pokeBA0(chip, BA0_SERMC1, 0);
2899
2900
/*
2901
* If we are in AC97 mode, then we must set the part to a host controlled
2902
* AC-link. Otherwise, we won't be able to bring up the link.
2903
*/
2904
#ifdef CONFIG_SND_CS46XX_NEW_DSP
2905
snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_2_0 |
2906
SERACC_TWO_CODECS); /* 2.00 dual codecs */
2907
/* snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_2_0); */ /* 2.00 codec */
2908
#else
2909
snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_1_03); /* 1.03 codec */
2910
#endif
2911
2912
/*
2913
* Drive the ARST# pin low for a minimum of 1uS (as defined in the AC97
2914
* spec) and then drive it high. This is done for non AC97 modes since
2915
* there might be logic external to the CS461x that uses the ARST# line
2916
* for a reset.
2917
*/
2918
snd_cs46xx_pokeBA0(chip, BA0_ACCTL, 0);
2919
#ifdef CONFIG_SND_CS46XX_NEW_DSP
2920
snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, 0);
2921
#endif
2922
udelay(50);
2923
snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_RSTN);
2924
#ifdef CONFIG_SND_CS46XX_NEW_DSP
2925
snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_RSTN);
2926
#endif
2927
2928
/*
2929
* The first thing we do here is to enable sync generation. As soon
2930
* as we start receiving bit clock, we'll start producing the SYNC
2931
* signal.
2932
*/
2933
snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_ESYN | ACCTL_RSTN);
2934
#ifdef CONFIG_SND_CS46XX_NEW_DSP
2935
snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_ESYN | ACCTL_RSTN);
2936
#endif
2937
2938
/*
2939
* Now wait for a short while to allow the AC97 part to start
2940
* generating bit clock (so we don't try to start the PLL without an
2941
* input clock).
2942
*/
2943
mdelay(10);
2944
2945
/*
2946
* Set the serial port timing configuration, so that
2947
* the clock control circuit gets its clock from the correct place.
2948
*/
2949
snd_cs46xx_pokeBA0(chip, BA0_SERMC1, SERMC1_PTC_AC97);
2950
2951
/*
2952
* Write the selected clock control setup to the hardware. Do not turn on
2953
* SWCE yet (if requested), so that the devices clocked by the output of
2954
* PLL are not clocked until the PLL is stable.
2955
*/
2956
snd_cs46xx_pokeBA0(chip, BA0_PLLCC, PLLCC_LPF_1050_2780_KHZ | PLLCC_CDR_73_104_MHZ);
2957
snd_cs46xx_pokeBA0(chip, BA0_PLLM, 0x3a);
2958
snd_cs46xx_pokeBA0(chip, BA0_CLKCR2, CLKCR2_PDIVS_8);
2959
2960
/*
2961
* Power up the PLL.
2962
*/
2963
snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, CLKCR1_PLLP);
2964
2965
/*
2966
* Wait until the PLL has stabilized.
2967
*/
2968
msleep(100);
2969
2970
/*
2971
* Turn on clocking of the core so that we can setup the serial ports.
2972
*/
2973
snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, CLKCR1_PLLP | CLKCR1_SWCE);
2974
2975
/*
2976
* Enable FIFO Host Bypass
2977
*/
2978
snd_cs46xx_pokeBA0(chip, BA0_SERBCF, SERBCF_HBP);
2979
2980
/*
2981
* Fill the serial port FIFOs with silence.
2982
*/
2983
snd_cs46xx_clear_serial_FIFOs(chip);
2984
2985
/*
2986
* Set the serial port FIFO pointer to the first sample in the FIFO.
2987
*/
2988
/* snd_cs46xx_pokeBA0(chip, BA0_SERBSP, 0); */
2989
2990
/*
2991
* Write the serial port configuration to the part. The master
2992
* enable bit is not set until all other values have been written.
2993
*/
2994
snd_cs46xx_pokeBA0(chip, BA0_SERC1, SERC1_SO1F_AC97 | SERC1_SO1EN);
2995
snd_cs46xx_pokeBA0(chip, BA0_SERC2, SERC2_SI1F_AC97 | SERC1_SO1EN);
2996
snd_cs46xx_pokeBA0(chip, BA0_SERMC1, SERMC1_PTC_AC97 | SERMC1_MSPE);
2997
2998
2999
#ifdef CONFIG_SND_CS46XX_NEW_DSP
3000
snd_cs46xx_pokeBA0(chip, BA0_SERC7, SERC7_ASDI2EN);
3001
snd_cs46xx_pokeBA0(chip, BA0_SERC3, 0);
3002
snd_cs46xx_pokeBA0(chip, BA0_SERC4, 0);
3003
snd_cs46xx_pokeBA0(chip, BA0_SERC5, 0);
3004
snd_cs46xx_pokeBA0(chip, BA0_SERC6, 1);
3005
#endif
3006
3007
mdelay(5);
3008
3009
3010
/*
3011
* Wait for the codec ready signal from the AC97 codec.
3012
*/
3013
timeout = 150;
3014
while (timeout-- > 0) {
3015
/*
3016
* Read the AC97 status register to see if we've seen a CODEC READY
3017
* signal from the AC97 codec.
3018
*/
3019
if (snd_cs46xx_peekBA0(chip, BA0_ACSTS) & ACSTS_CRDY)
3020
goto ok1;
3021
msleep(10);
3022
}
3023
3024
3025
dev_err(chip->card->dev,
3026
"create - never read codec ready from AC'97\n");
3027
dev_err(chip->card->dev,
3028
"it is not probably bug, try to use CS4236 driver\n");
3029
return -EIO;
3030
ok1:
3031
#ifdef CONFIG_SND_CS46XX_NEW_DSP
3032
{
3033
int count;
3034
for (count = 0; count < 150; count++) {
3035
/* First, we want to wait for a short time. */
3036
udelay(25);
3037
3038
if (snd_cs46xx_peekBA0(chip, BA0_ACSTS2) & ACSTS_CRDY)
3039
break;
3040
}
3041
3042
/*
3043
* Make sure CODEC is READY.
3044
*/
3045
if (!(snd_cs46xx_peekBA0(chip, BA0_ACSTS2) & ACSTS_CRDY))
3046
dev_dbg(chip->card->dev,
3047
"never read card ready from secondary AC'97\n");
3048
}
3049
#endif
3050
3051
/*
3052
* Assert the vaid frame signal so that we can start sending commands
3053
* to the AC97 codec.
3054
*/
3055
snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN);
3056
#ifdef CONFIG_SND_CS46XX_NEW_DSP
3057
snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN);
3058
#endif
3059
3060
3061
/*
3062
* Wait until we've sampled input slots 3 and 4 as valid, meaning that
3063
* the codec is pumping ADC data across the AC-link.
3064
*/
3065
timeout = 150;
3066
while (timeout-- > 0) {
3067
/*
3068
* Read the input slot valid register and see if input slots 3 and
3069
* 4 are valid yet.
3070
*/
3071
if ((snd_cs46xx_peekBA0(chip, BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) == (ACISV_ISV3 | ACISV_ISV4))
3072
goto ok2;
3073
msleep(10);
3074
}
3075
3076
#ifndef CONFIG_SND_CS46XX_NEW_DSP
3077
dev_err(chip->card->dev,
3078
"create - never read ISV3 & ISV4 from AC'97\n");
3079
return -EIO;
3080
#else
3081
/* This may happen on a cold boot with a Terratec SiXPack 5.1.
3082
Reloading the driver may help, if there's other soundcards
3083
with the same problem I would like to know. (Benny) */
3084
3085
dev_err(chip->card->dev, "never read ISV3 & ISV4 from AC'97\n");
3086
dev_err(chip->card->dev,
3087
"Try reloading the ALSA driver, if you find something\n");
3088
dev_err(chip->card->dev,
3089
"broken or not working on your soundcard upon\n");
3090
dev_err(chip->card->dev,
3091
"this message please report to [email protected]\n");
3092
3093
return -EIO;
3094
#endif
3095
ok2:
3096
3097
/*
3098
* Now, assert valid frame and the slot 3 and 4 valid bits. This will
3099
* commense the transfer of digital audio data to the AC97 codec.
3100
*/
3101
3102
snd_cs46xx_pokeBA0(chip, BA0_ACOSV, ACOSV_SLV3 | ACOSV_SLV4);
3103
3104
3105
/*
3106
* Power down the DAC and ADC. We will power them up (if) when we need
3107
* them.
3108
*/
3109
/* snd_cs46xx_pokeBA0(chip, BA0_AC97_POWERDOWN, 0x300); */
3110
3111
/*
3112
* Turn off the Processor by turning off the software clock enable flag in
3113
* the clock control register.
3114
*/
3115
/* tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1) & ~CLKCR1_SWCE; */
3116
/* snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); */
3117
3118
return 0;
3119
}
3120
3121
/*
3122
* start and load DSP
3123
*/
3124
3125
static void cs46xx_enable_stream_irqs(struct snd_cs46xx *chip)
3126
{
3127
unsigned int tmp;
3128
3129
snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_IEV | HICR_CHGM);
3130
3131
tmp = snd_cs46xx_peek(chip, BA1_PFIE);
3132
tmp &= ~0x0000f03f;
3133
snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt enable */
3134
3135
tmp = snd_cs46xx_peek(chip, BA1_CIE);
3136
tmp &= ~0x0000003f;
3137
tmp |= 0x00000001;
3138
snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt enable */
3139
}
3140
3141
int snd_cs46xx_start_dsp(struct snd_cs46xx *chip)
3142
{
3143
unsigned int tmp;
3144
#ifdef CONFIG_SND_CS46XX_NEW_DSP
3145
int i;
3146
#endif
3147
int err;
3148
3149
/*
3150
* Reset the processor.
3151
*/
3152
snd_cs46xx_reset(chip);
3153
/*
3154
* Download the image to the processor.
3155
*/
3156
#ifdef CONFIG_SND_CS46XX_NEW_DSP
3157
for (i = 0; i < CS46XX_DSP_MODULES; i++) {
3158
err = load_firmware(chip, &chip->modules[i], module_names[i]);
3159
if (err < 0) {
3160
dev_err(chip->card->dev, "firmware load error [%s]\n",
3161
module_names[i]);
3162
return err;
3163
}
3164
err = cs46xx_dsp_load_module(chip, chip->modules[i]);
3165
if (err < 0) {
3166
dev_err(chip->card->dev, "image download error [%s]\n",
3167
module_names[i]);
3168
return err;
3169
}
3170
}
3171
3172
if (cs46xx_dsp_scb_and_task_init(chip) < 0)
3173
return -EIO;
3174
#else
3175
err = load_firmware(chip);
3176
if (err < 0)
3177
return err;
3178
3179
/* old image */
3180
err = snd_cs46xx_download_image(chip);
3181
if (err < 0) {
3182
dev_err(chip->card->dev, "image download error\n");
3183
return err;
3184
}
3185
3186
/*
3187
* Stop playback DMA.
3188
*/
3189
tmp = snd_cs46xx_peek(chip, BA1_PCTL);
3190
chip->play_ctl = tmp & 0xffff0000;
3191
snd_cs46xx_poke(chip, BA1_PCTL, tmp & 0x0000ffff);
3192
#endif
3193
3194
/*
3195
* Stop capture DMA.
3196
*/
3197
tmp = snd_cs46xx_peek(chip, BA1_CCTL);
3198
chip->capt.ctl = tmp & 0x0000ffff;
3199
snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000);
3200
3201
mdelay(5);
3202
3203
snd_cs46xx_set_play_sample_rate(chip, 8000);
3204
snd_cs46xx_set_capture_sample_rate(chip, 8000);
3205
3206
snd_cs46xx_proc_start(chip);
3207
3208
cs46xx_enable_stream_irqs(chip);
3209
3210
#ifndef CONFIG_SND_CS46XX_NEW_DSP
3211
/* set the attenuation to 0dB */
3212
snd_cs46xx_poke(chip, BA1_PVOL, 0x80008000);
3213
snd_cs46xx_poke(chip, BA1_CVOL, 0x80008000);
3214
#endif
3215
3216
return 0;
3217
}
3218
3219
3220
/*
3221
* AMP control - null AMP
3222
*/
3223
3224
static void amp_none(struct snd_cs46xx *chip, int change)
3225
{
3226
}
3227
3228
#ifdef CONFIG_SND_CS46XX_NEW_DSP
3229
static int voyetra_setup_eapd_slot(struct snd_cs46xx *chip)
3230
{
3231
3232
u32 idx, valid_slots,tmp,powerdown = 0;
3233
u16 modem_power,pin_config,logic_type;
3234
3235
dev_dbg(chip->card->dev, "cs46xx_setup_eapd_slot()+\n");
3236
3237
/*
3238
* See if the devices are powered down. If so, we must power them up first
3239
* or they will not respond.
3240
*/
3241
tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1);
3242
3243
if (!(tmp & CLKCR1_SWCE)) {
3244
snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp | CLKCR1_SWCE);
3245
powerdown = 1;
3246
}
3247
3248
/*
3249
* Clear PRA. The Bonzo chip will be used for GPIO not for modem
3250
* stuff.
3251
*/
3252
if(chip->nr_ac97_codecs != 2) {
3253
dev_err(chip->card->dev,
3254
"cs46xx_setup_eapd_slot() - no secondary codec configured\n");
3255
return -EINVAL;
3256
}
3257
3258
modem_power = snd_cs46xx_codec_read (chip,
3259
AC97_EXTENDED_MSTATUS,
3260
CS46XX_SECONDARY_CODEC_INDEX);
3261
modem_power &=0xFEFF;
3262
3263
snd_cs46xx_codec_write(chip,
3264
AC97_EXTENDED_MSTATUS, modem_power,
3265
CS46XX_SECONDARY_CODEC_INDEX);
3266
3267
/*
3268
* Set GPIO pin's 7 and 8 so that they are configured for output.
3269
*/
3270
pin_config = snd_cs46xx_codec_read (chip,
3271
AC97_GPIO_CFG,
3272
CS46XX_SECONDARY_CODEC_INDEX);
3273
pin_config &=0x27F;
3274
3275
snd_cs46xx_codec_write(chip,
3276
AC97_GPIO_CFG, pin_config,
3277
CS46XX_SECONDARY_CODEC_INDEX);
3278
3279
/*
3280
* Set GPIO pin's 7 and 8 so that they are compatible with CMOS logic.
3281
*/
3282
3283
logic_type = snd_cs46xx_codec_read(chip, AC97_GPIO_POLARITY,
3284
CS46XX_SECONDARY_CODEC_INDEX);
3285
logic_type &=0x27F;
3286
3287
snd_cs46xx_codec_write (chip, AC97_GPIO_POLARITY, logic_type,
3288
CS46XX_SECONDARY_CODEC_INDEX);
3289
3290
valid_slots = snd_cs46xx_peekBA0(chip, BA0_ACOSV);
3291
valid_slots |= 0x200;
3292
snd_cs46xx_pokeBA0(chip, BA0_ACOSV, valid_slots);
3293
3294
if ( cs46xx_wait_for_fifo(chip,1) ) {
3295
dev_dbg(chip->card->dev, "FIFO is busy\n");
3296
3297
return -EINVAL;
3298
}
3299
3300
/*
3301
* Fill slots 12 with the correct value for the GPIO pins.
3302
*/
3303
for(idx = 0x90; idx <= 0x9F; idx++) {
3304
/*
3305
* Initialize the fifo so that bits 7 and 8 are on.
3306
*
3307
* Remember that the GPIO pins in bonzo are shifted by 4 bits to
3308
* the left. 0x1800 corresponds to bits 7 and 8.
3309
*/
3310
snd_cs46xx_pokeBA0(chip, BA0_SERBWP, 0x1800);
3311
3312
/*
3313
* Wait for command to complete
3314
*/
3315
if ( cs46xx_wait_for_fifo(chip,200) ) {
3316
dev_dbg(chip->card->dev,
3317
"failed waiting for FIFO at addr (%02X)\n",
3318
idx);
3319
3320
return -EINVAL;
3321
}
3322
3323
/*
3324
* Write the serial port FIFO index.
3325
*/
3326
snd_cs46xx_pokeBA0(chip, BA0_SERBAD, idx);
3327
3328
/*
3329
* Tell the serial port to load the new value into the FIFO location.
3330
*/
3331
snd_cs46xx_pokeBA0(chip, BA0_SERBCM, SERBCM_WRC);
3332
}
3333
3334
/* wait for last command to complete */
3335
cs46xx_wait_for_fifo(chip,200);
3336
3337
/*
3338
* Now, if we powered up the devices, then power them back down again.
3339
* This is kinda ugly, but should never happen.
3340
*/
3341
if (powerdown)
3342
snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp);
3343
3344
return 0;
3345
}
3346
#endif
3347
3348
/*
3349
* Crystal EAPD mode
3350
*/
3351
3352
static void amp_voyetra(struct snd_cs46xx *chip, int change)
3353
{
3354
/* Manage the EAPD bit on the Crystal 4297
3355
and the Analog AD1885 */
3356
3357
#ifdef CONFIG_SND_CS46XX_NEW_DSP
3358
int old = chip->amplifier;
3359
#endif
3360
int oval, val;
3361
3362
chip->amplifier += change;
3363
oval = snd_cs46xx_codec_read(chip, AC97_POWERDOWN,
3364
CS46XX_PRIMARY_CODEC_INDEX);
3365
val = oval;
3366
if (chip->amplifier) {
3367
/* Turn the EAPD amp on */
3368
val |= 0x8000;
3369
} else {
3370
/* Turn the EAPD amp off */
3371
val &= ~0x8000;
3372
}
3373
if (val != oval) {
3374
snd_cs46xx_codec_write(chip, AC97_POWERDOWN, val,
3375
CS46XX_PRIMARY_CODEC_INDEX);
3376
if (chip->eapd_switch)
3377
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
3378
&chip->eapd_switch->id);
3379
}
3380
3381
#ifdef CONFIG_SND_CS46XX_NEW_DSP
3382
if (chip->amplifier && !old) {
3383
voyetra_setup_eapd_slot(chip);
3384
}
3385
#endif
3386
}
3387
3388
static void hercules_init(struct snd_cs46xx *chip)
3389
{
3390
/* default: AMP off, and SPDIF input optical */
3391
snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, EGPIODR_GPOE0);
3392
snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, EGPIODR_GPOE0);
3393
}
3394
3395
3396
/*
3397
* Game Theatre XP card - EGPIO[2] is used to enable the external amp.
3398
*/
3399
static void amp_hercules(struct snd_cs46xx *chip, int change)
3400
{
3401
int old = chip->amplifier;
3402
int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR);
3403
int val2 = snd_cs46xx_peekBA0(chip, BA0_EGPIOPTR);
3404
3405
chip->amplifier += change;
3406
if (chip->amplifier && !old) {
3407
dev_dbg(chip->card->dev, "Hercules amplifier ON\n");
3408
3409
snd_cs46xx_pokeBA0(chip, BA0_EGPIODR,
3410
EGPIODR_GPOE2 | val1); /* enable EGPIO2 output */
3411
snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR,
3412
EGPIOPTR_GPPT2 | val2); /* open-drain on output */
3413
} else if (old && !chip->amplifier) {
3414
dev_dbg(chip->card->dev, "Hercules amplifier OFF\n");
3415
snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, val1 & ~EGPIODR_GPOE2); /* disable */
3416
snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, val2 & ~EGPIOPTR_GPPT2); /* disable */
3417
}
3418
}
3419
3420
static void voyetra_mixer_init (struct snd_cs46xx *chip)
3421
{
3422
dev_dbg(chip->card->dev, "initializing Voyetra mixer\n");
3423
3424
/* Enable SPDIF out */
3425
snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, EGPIODR_GPOE0);
3426
snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, EGPIODR_GPOE0);
3427
}
3428
3429
static void hercules_mixer_init (struct snd_cs46xx *chip)
3430
{
3431
#ifdef CONFIG_SND_CS46XX_NEW_DSP
3432
unsigned int idx;
3433
int err;
3434
struct snd_card *card = chip->card;
3435
#endif
3436
3437
/* set EGPIO to default */
3438
hercules_init(chip);
3439
3440
dev_dbg(chip->card->dev, "initializing Hercules mixer\n");
3441
3442
#ifdef CONFIG_SND_CS46XX_NEW_DSP
3443
if (chip->in_suspend)
3444
return;
3445
3446
for (idx = 0 ; idx < ARRAY_SIZE(snd_hercules_controls); idx++) {
3447
struct snd_kcontrol *kctl;
3448
3449
kctl = snd_ctl_new1(&snd_hercules_controls[idx], chip);
3450
err = snd_ctl_add(card, kctl);
3451
if (err < 0) {
3452
dev_err(card->dev,
3453
"failed to initialize Hercules mixer (%d)\n",
3454
err);
3455
break;
3456
}
3457
}
3458
#endif
3459
}
3460
3461
3462
#if 0
3463
/*
3464
* Untested
3465
*/
3466
3467
static void amp_voyetra_4294(struct snd_cs46xx *chip, int change)
3468
{
3469
chip->amplifier += change;
3470
3471
if (chip->amplifier) {
3472
/* Switch the GPIO pins 7 and 8 to open drain */
3473
snd_cs46xx_codec_write(chip, 0x4C,
3474
snd_cs46xx_codec_read(chip, 0x4C) & 0xFE7F);
3475
snd_cs46xx_codec_write(chip, 0x4E,
3476
snd_cs46xx_codec_read(chip, 0x4E) | 0x0180);
3477
/* Now wake the AMP (this might be backwards) */
3478
snd_cs46xx_codec_write(chip, 0x54,
3479
snd_cs46xx_codec_read(chip, 0x54) & ~0x0180);
3480
} else {
3481
snd_cs46xx_codec_write(chip, 0x54,
3482
snd_cs46xx_codec_read(chip, 0x54) | 0x0180);
3483
}
3484
}
3485
#endif
3486
3487
3488
/*
3489
* Handle the CLKRUN on a thinkpad. We must disable CLKRUN support
3490
* whenever we need to beat on the chip.
3491
*
3492
* The original idea and code for this hack comes from David Kaiser at
3493
* Linuxcare. Perhaps one day Crystal will document their chips well
3494
* enough to make them useful.
3495
*/
3496
3497
static void clkrun_hack(struct snd_cs46xx *chip, int change)
3498
{
3499
u16 control, nval;
3500
3501
if (!chip->acpi_port)
3502
return;
3503
3504
chip->amplifier += change;
3505
3506
/* Read ACPI port */
3507
nval = control = inw(chip->acpi_port + 0x10);
3508
3509
/* Flip CLKRUN off while running */
3510
if (! chip->amplifier)
3511
nval |= 0x2000;
3512
else
3513
nval &= ~0x2000;
3514
if (nval != control)
3515
outw(nval, chip->acpi_port + 0x10);
3516
}
3517
3518
3519
/*
3520
* detect intel piix4
3521
*/
3522
static void clkrun_init(struct snd_cs46xx *chip)
3523
{
3524
struct pci_dev *pdev;
3525
u8 pp;
3526
3527
chip->acpi_port = 0;
3528
3529
pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
3530
PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
3531
if (pdev == NULL)
3532
return; /* Not a thinkpad thats for sure */
3533
3534
/* Find the control port */
3535
pci_read_config_byte(pdev, 0x41, &pp);
3536
chip->acpi_port = pp << 8;
3537
pci_dev_put(pdev);
3538
}
3539
3540
3541
/*
3542
* Card subid table
3543
*/
3544
3545
struct cs_card_type
3546
{
3547
u16 vendor;
3548
u16 id;
3549
char *name;
3550
void (*init)(struct snd_cs46xx *);
3551
void (*amp)(struct snd_cs46xx *, int);
3552
void (*active)(struct snd_cs46xx *, int);
3553
void (*mixer_init)(struct snd_cs46xx *);
3554
};
3555
3556
static struct cs_card_type cards[] = {
3557
{
3558
.vendor = 0x1489,
3559
.id = 0x7001,
3560
.name = "Genius Soundmaker 128 value",
3561
/* nothing special */
3562
},
3563
{
3564
.vendor = 0x5053,
3565
.id = 0x3357,
3566
.name = "Voyetra",
3567
.amp = amp_voyetra,
3568
.mixer_init = voyetra_mixer_init,
3569
},
3570
{
3571
.vendor = 0x1071,
3572
.id = 0x6003,
3573
.name = "Mitac MI6020/21",
3574
.amp = amp_voyetra,
3575
},
3576
/* Hercules Game Theatre XP */
3577
{
3578
.vendor = 0x14af, /* Guillemot Corporation */
3579
.id = 0x0050,
3580
.name = "Hercules Game Theatre XP",
3581
.amp = amp_hercules,
3582
.mixer_init = hercules_mixer_init,
3583
},
3584
{
3585
.vendor = 0x1681,
3586
.id = 0x0050,
3587
.name = "Hercules Game Theatre XP",
3588
.amp = amp_hercules,
3589
.mixer_init = hercules_mixer_init,
3590
},
3591
{
3592
.vendor = 0x1681,
3593
.id = 0x0051,
3594
.name = "Hercules Game Theatre XP",
3595
.amp = amp_hercules,
3596
.mixer_init = hercules_mixer_init,
3597
3598
},
3599
{
3600
.vendor = 0x1681,
3601
.id = 0x0052,
3602
.name = "Hercules Game Theatre XP",
3603
.amp = amp_hercules,
3604
.mixer_init = hercules_mixer_init,
3605
},
3606
{
3607
.vendor = 0x1681,
3608
.id = 0x0053,
3609
.name = "Hercules Game Theatre XP",
3610
.amp = amp_hercules,
3611
.mixer_init = hercules_mixer_init,
3612
},
3613
{
3614
.vendor = 0x1681,
3615
.id = 0x0054,
3616
.name = "Hercules Game Theatre XP",
3617
.amp = amp_hercules,
3618
.mixer_init = hercules_mixer_init,
3619
},
3620
/* Herculess Fortissimo */
3621
{
3622
.vendor = 0x1681,
3623
.id = 0xa010,
3624
.name = "Hercules Gamesurround Fortissimo II",
3625
},
3626
{
3627
.vendor = 0x1681,
3628
.id = 0xa011,
3629
.name = "Hercules Gamesurround Fortissimo III 7.1",
3630
},
3631
/* Teratec */
3632
{
3633
.vendor = 0x153b,
3634
.id = 0x112e,
3635
.name = "Terratec DMX XFire 1024",
3636
},
3637
{
3638
.vendor = 0x153b,
3639
.id = 0x1136,
3640
.name = "Terratec SiXPack 5.1",
3641
},
3642
/* Not sure if the 570 needs the clkrun hack */
3643
{
3644
.vendor = PCI_VENDOR_ID_IBM,
3645
.id = 0x0132,
3646
.name = "Thinkpad 570",
3647
.init = clkrun_init,
3648
.active = clkrun_hack,
3649
},
3650
{
3651
.vendor = PCI_VENDOR_ID_IBM,
3652
.id = 0x0153,
3653
.name = "Thinkpad 600X/A20/T20",
3654
.init = clkrun_init,
3655
.active = clkrun_hack,
3656
},
3657
{
3658
.vendor = PCI_VENDOR_ID_IBM,
3659
.id = 0x1010,
3660
.name = "Thinkpad 600E (unsupported)",
3661
},
3662
{} /* terminator */
3663
};
3664
3665
3666
/*
3667
* APM support
3668
*/
3669
#ifdef CONFIG_PM_SLEEP
3670
static const unsigned int saved_regs[] = {
3671
BA0_ACOSV,
3672
/*BA0_ASER_FADDR,*/
3673
BA0_ASER_MASTER,
3674
BA1_PVOL,
3675
BA1_CVOL,
3676
};
3677
3678
static int snd_cs46xx_suspend(struct device *dev)
3679
{
3680
struct snd_card *card = dev_get_drvdata(dev);
3681
struct snd_cs46xx *chip = card->private_data;
3682
int i, amp_saved;
3683
3684
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
3685
chip->in_suspend = 1;
3686
// chip->ac97_powerdown = snd_cs46xx_codec_read(chip, AC97_POWER_CONTROL);
3687
// chip->ac97_general_purpose = snd_cs46xx_codec_read(chip, BA0_AC97_GENERAL_PURPOSE);
3688
3689
snd_ac97_suspend(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]);
3690
snd_ac97_suspend(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]);
3691
3692
/* save some registers */
3693
for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
3694
chip->saved_regs[i] = snd_cs46xx_peekBA0(chip, saved_regs[i]);
3695
3696
amp_saved = chip->amplifier;
3697
/* turn off amp */
3698
chip->amplifier_ctrl(chip, -chip->amplifier);
3699
snd_cs46xx_hw_stop(chip);
3700
/* disable CLKRUN */
3701
chip->active_ctrl(chip, -chip->amplifier);
3702
chip->amplifier = amp_saved; /* restore the status */
3703
return 0;
3704
}
3705
3706
static int snd_cs46xx_resume(struct device *dev)
3707
{
3708
struct snd_card *card = dev_get_drvdata(dev);
3709
struct snd_cs46xx *chip = card->private_data;
3710
int amp_saved;
3711
#ifdef CONFIG_SND_CS46XX_NEW_DSP
3712
int i;
3713
#endif
3714
unsigned int tmp;
3715
3716
amp_saved = chip->amplifier;
3717
chip->amplifier = 0;
3718
chip->active_ctrl(chip, 1); /* force to on */
3719
3720
snd_cs46xx_chip_init(chip);
3721
3722
snd_cs46xx_reset(chip);
3723
#ifdef CONFIG_SND_CS46XX_NEW_DSP
3724
cs46xx_dsp_resume(chip);
3725
/* restore some registers */
3726
for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
3727
snd_cs46xx_pokeBA0(chip, saved_regs[i], chip->saved_regs[i]);
3728
#else
3729
snd_cs46xx_download_image(chip);
3730
#endif
3731
3732
#if 0
3733
snd_cs46xx_codec_write(chip, BA0_AC97_GENERAL_PURPOSE,
3734
chip->ac97_general_purpose);
3735
snd_cs46xx_codec_write(chip, AC97_POWER_CONTROL,
3736
chip->ac97_powerdown);
3737
mdelay(10);
3738
snd_cs46xx_codec_write(chip, BA0_AC97_POWERDOWN,
3739
chip->ac97_powerdown);
3740
mdelay(5);
3741
#endif
3742
3743
snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]);
3744
snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]);
3745
3746
/*
3747
* Stop capture DMA.
3748
*/
3749
tmp = snd_cs46xx_peek(chip, BA1_CCTL);
3750
chip->capt.ctl = tmp & 0x0000ffff;
3751
snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000);
3752
3753
mdelay(5);
3754
3755
/* reset playback/capture */
3756
snd_cs46xx_set_play_sample_rate(chip, 8000);
3757
snd_cs46xx_set_capture_sample_rate(chip, 8000);
3758
snd_cs46xx_proc_start(chip);
3759
3760
cs46xx_enable_stream_irqs(chip);
3761
3762
if (amp_saved)
3763
chip->amplifier_ctrl(chip, 1); /* turn amp on */
3764
else
3765
chip->active_ctrl(chip, -1); /* disable CLKRUN */
3766
chip->amplifier = amp_saved;
3767
chip->in_suspend = 0;
3768
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
3769
return 0;
3770
}
3771
3772
SIMPLE_DEV_PM_OPS(snd_cs46xx_pm, snd_cs46xx_suspend, snd_cs46xx_resume);
3773
#endif /* CONFIG_PM_SLEEP */
3774
3775
3776
/*
3777
*/
3778
3779
int snd_cs46xx_create(struct snd_card *card,
3780
struct pci_dev *pci,
3781
int external_amp, int thinkpad)
3782
{
3783
struct snd_cs46xx *chip = card->private_data;
3784
int err, idx;
3785
struct snd_cs46xx_region *region;
3786
struct cs_card_type *cp;
3787
u16 ss_card, ss_vendor;
3788
3789
/* enable PCI device */
3790
err = pcim_enable_device(pci);
3791
if (err < 0)
3792
return err;
3793
3794
spin_lock_init(&chip->reg_lock);
3795
#ifdef CONFIG_SND_CS46XX_NEW_DSP
3796
mutex_init(&chip->spos_mutex);
3797
#endif
3798
chip->card = card;
3799
chip->pci = pci;
3800
chip->irq = -1;
3801
3802
err = pcim_request_all_regions(pci, "CS46xx");
3803
if (err < 0)
3804
return err;
3805
chip->ba0_addr = pci_resource_start(pci, 0);
3806
chip->ba1_addr = pci_resource_start(pci, 1);
3807
if (chip->ba0_addr == 0 || chip->ba0_addr == (unsigned long)~0 ||
3808
chip->ba1_addr == 0 || chip->ba1_addr == (unsigned long)~0) {
3809
dev_err(chip->card->dev,
3810
"wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n",
3811
chip->ba0_addr, chip->ba1_addr);
3812
return -ENOMEM;
3813
}
3814
3815
region = &chip->region.name.ba0;
3816
strscpy(region->name, "CS46xx_BA0");
3817
region->base = chip->ba0_addr;
3818
region->size = CS46XX_BA0_SIZE;
3819
3820
region = &chip->region.name.data0;
3821
strscpy(region->name, "CS46xx_BA1_data0");
3822
region->base = chip->ba1_addr + BA1_SP_DMEM0;
3823
region->size = CS46XX_BA1_DATA0_SIZE;
3824
3825
region = &chip->region.name.data1;
3826
strscpy(region->name, "CS46xx_BA1_data1");
3827
region->base = chip->ba1_addr + BA1_SP_DMEM1;
3828
region->size = CS46XX_BA1_DATA1_SIZE;
3829
3830
region = &chip->region.name.pmem;
3831
strscpy(region->name, "CS46xx_BA1_pmem");
3832
region->base = chip->ba1_addr + BA1_SP_PMEM;
3833
region->size = CS46XX_BA1_PRG_SIZE;
3834
3835
region = &chip->region.name.reg;
3836
strscpy(region->name, "CS46xx_BA1_reg");
3837
region->base = chip->ba1_addr + BA1_SP_REG;
3838
region->size = CS46XX_BA1_REG_SIZE;
3839
3840
/* set up amp and clkrun hack */
3841
pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &ss_vendor);
3842
pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &ss_card);
3843
3844
for (cp = &cards[0]; cp->name; cp++) {
3845
if (cp->vendor == ss_vendor && cp->id == ss_card) {
3846
dev_dbg(chip->card->dev, "hack for %s enabled\n",
3847
cp->name);
3848
3849
chip->amplifier_ctrl = cp->amp;
3850
chip->active_ctrl = cp->active;
3851
chip->mixer_init = cp->mixer_init;
3852
3853
if (cp->init)
3854
cp->init(chip);
3855
break;
3856
}
3857
}
3858
3859
if (external_amp) {
3860
dev_info(chip->card->dev,
3861
"Crystal EAPD support forced on.\n");
3862
chip->amplifier_ctrl = amp_voyetra;
3863
}
3864
3865
if (thinkpad) {
3866
dev_info(chip->card->dev,
3867
"Activating CLKRUN hack for Thinkpad.\n");
3868
chip->active_ctrl = clkrun_hack;
3869
clkrun_init(chip);
3870
}
3871
3872
if (chip->amplifier_ctrl == NULL)
3873
chip->amplifier_ctrl = amp_none;
3874
if (chip->active_ctrl == NULL)
3875
chip->active_ctrl = amp_none;
3876
3877
chip->active_ctrl(chip, 1); /* enable CLKRUN */
3878
3879
pci_set_master(pci);
3880
3881
for (idx = 0; idx < 5; idx++) {
3882
region = &chip->region.idx[idx];
3883
region->remap_addr = devm_ioremap(&pci->dev, region->base,
3884
region->size);
3885
if (region->remap_addr == NULL) {
3886
dev_err(chip->card->dev,
3887
"%s ioremap problem\n", region->name);
3888
return -ENOMEM;
3889
}
3890
}
3891
3892
if (devm_request_irq(&pci->dev, pci->irq, snd_cs46xx_interrupt,
3893
IRQF_SHARED, KBUILD_MODNAME, chip)) {
3894
dev_err(chip->card->dev, "unable to grab IRQ %d\n", pci->irq);
3895
return -EBUSY;
3896
}
3897
chip->irq = pci->irq;
3898
card->sync_irq = chip->irq;
3899
card->private_free = snd_cs46xx_free;
3900
3901
#ifdef CONFIG_SND_CS46XX_NEW_DSP
3902
chip->dsp_spos_instance = cs46xx_dsp_spos_create(chip);
3903
if (!chip->dsp_spos_instance)
3904
return -ENOMEM;
3905
#endif
3906
3907
err = snd_cs46xx_chip_init(chip);
3908
if (err < 0)
3909
return err;
3910
3911
snd_cs46xx_proc_init(card, chip);
3912
3913
#ifdef CONFIG_PM_SLEEP
3914
chip->saved_regs = devm_kmalloc_array(&pci->dev,
3915
ARRAY_SIZE(saved_regs),
3916
sizeof(*chip->saved_regs),
3917
GFP_KERNEL);
3918
if (!chip->saved_regs)
3919
return -ENOMEM;
3920
#endif
3921
3922
chip->active_ctrl(chip, -1); /* disable CLKRUN */
3923
return 0;
3924
}
3925
3926