Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/isa/opti9xx/opti92x-ad1848.c
29266 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
card-opti92x-ad1848.c - driver for OPTi 82c92x based soundcards.
4
Copyright (C) 1998-2000 by Massimo Piccioni <[email protected]>
5
6
Part of this code was developed at the Italian Ministry of Air Defence,
7
Sixth Division (oh, che pace ...), Rome.
8
9
Thanks to Maria Grazia Pollarini, Salvatore Vassallo.
10
11
*/
12
13
14
#include <linux/init.h>
15
#include <linux/err.h>
16
#include <linux/isa.h>
17
#include <linux/delay.h>
18
#include <linux/pnp.h>
19
#include <linux/module.h>
20
#include <linux/io.h>
21
#include <asm/dma.h>
22
#include <sound/core.h>
23
#include <sound/tlv.h>
24
#include <sound/wss.h>
25
#include <sound/mpu401.h>
26
#include <sound/opl3.h>
27
#ifndef OPTi93X
28
#include <sound/opl4.h>
29
#endif
30
#define SNDRV_LEGACY_FIND_FREE_IOPORT
31
#define SNDRV_LEGACY_FIND_FREE_IRQ
32
#define SNDRV_LEGACY_FIND_FREE_DMA
33
#include <sound/initval.h>
34
35
MODULE_AUTHOR("Massimo Piccioni <[email protected]>");
36
MODULE_LICENSE("GPL");
37
#ifdef OPTi93X
38
MODULE_DESCRIPTION("OPTi93X");
39
#else /* OPTi93X */
40
#ifdef CS4231
41
MODULE_DESCRIPTION("OPTi92X - CS4231");
42
#else /* CS4231 */
43
MODULE_DESCRIPTION("OPTi92X - AD1848");
44
#endif /* CS4231 */
45
#endif /* OPTi93X */
46
47
static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
48
static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
49
//static bool enable = SNDRV_DEFAULT_ENABLE1; /* Enable this card */
50
#ifdef CONFIG_PNP
51
static bool isapnp = true; /* Enable ISA PnP detection */
52
#endif
53
static long port = SNDRV_DEFAULT_PORT1; /* 0x530,0xe80,0xf40,0x604 */
54
static long mpu_port = SNDRV_DEFAULT_PORT1; /* 0x300,0x310,0x320,0x330 */
55
static long fm_port = SNDRV_DEFAULT_PORT1; /* 0x388 */
56
static int irq = SNDRV_DEFAULT_IRQ1; /* 5,7,9,10,11 */
57
static int mpu_irq = SNDRV_DEFAULT_IRQ1; /* 5,7,9,10 */
58
static int dma1 = SNDRV_DEFAULT_DMA1; /* 0,1,3 */
59
#if defined(CS4231) || defined(OPTi93X)
60
static int dma2 = SNDRV_DEFAULT_DMA1; /* 0,1,3 */
61
#endif /* CS4231 || OPTi93X */
62
63
module_param(index, int, 0444);
64
MODULE_PARM_DESC(index, "Index value for opti9xx based soundcard.");
65
module_param(id, charp, 0444);
66
MODULE_PARM_DESC(id, "ID string for opti9xx based soundcard.");
67
//module_param(enable, bool, 0444);
68
//MODULE_PARM_DESC(enable, "Enable opti9xx soundcard.");
69
#ifdef CONFIG_PNP
70
module_param(isapnp, bool, 0444);
71
MODULE_PARM_DESC(isapnp, "Enable ISA PnP detection for specified soundcard.");
72
#endif
73
module_param_hw(port, long, ioport, 0444);
74
MODULE_PARM_DESC(port, "WSS port # for opti9xx driver.");
75
module_param_hw(mpu_port, long, ioport, 0444);
76
MODULE_PARM_DESC(mpu_port, "MPU-401 port # for opti9xx driver.");
77
module_param_hw(fm_port, long, ioport, 0444);
78
MODULE_PARM_DESC(fm_port, "FM port # for opti9xx driver.");
79
module_param_hw(irq, int, irq, 0444);
80
MODULE_PARM_DESC(irq, "WSS irq # for opti9xx driver.");
81
module_param_hw(mpu_irq, int, irq, 0444);
82
MODULE_PARM_DESC(mpu_irq, "MPU-401 irq # for opti9xx driver.");
83
module_param_hw(dma1, int, dma, 0444);
84
MODULE_PARM_DESC(dma1, "1st dma # for opti9xx driver.");
85
#if defined(CS4231) || defined(OPTi93X)
86
module_param_hw(dma2, int, dma, 0444);
87
MODULE_PARM_DESC(dma2, "2nd dma # for opti9xx driver.");
88
#endif /* CS4231 || OPTi93X */
89
90
#define OPTi9XX_HW_82C928 1
91
#define OPTi9XX_HW_82C929 2
92
#define OPTi9XX_HW_82C924 3
93
#define OPTi9XX_HW_82C925 4
94
#define OPTi9XX_HW_82C930 5
95
#define OPTi9XX_HW_82C931 6
96
#define OPTi9XX_HW_82C933 7
97
#define OPTi9XX_HW_LAST OPTi9XX_HW_82C933
98
99
#define OPTi9XX_MC_REG(n) n
100
101
#ifdef OPTi93X
102
103
#define OPTi93X_STATUS 0x02
104
#define OPTi93X_PORT(chip, r) ((chip)->port + OPTi93X_##r)
105
106
#define OPTi93X_IRQ_PLAYBACK 0x04
107
#define OPTi93X_IRQ_CAPTURE 0x08
108
109
#endif /* OPTi93X */
110
111
struct snd_opti9xx {
112
struct snd_card *card;
113
unsigned short hardware;
114
unsigned char password;
115
char name[7];
116
117
unsigned long mc_base;
118
struct resource *res_mc_base;
119
unsigned long mc_base_size;
120
#ifdef OPTi93X
121
unsigned long mc_indir_index;
122
struct resource *res_mc_indir;
123
#endif /* OPTi93X */
124
struct snd_wss *codec;
125
unsigned long pwd_reg;
126
127
spinlock_t lock;
128
129
long wss_base;
130
int irq;
131
};
132
133
static int snd_opti9xx_pnp_is_probed;
134
135
#ifdef CONFIG_PNP
136
137
static const struct pnp_card_device_id snd_opti9xx_pnpids[] = {
138
#ifndef OPTi93X
139
/* OPTi 82C924 */
140
{ .id = "OPT0924",
141
.devs = { { "OPT0000" }, { "OPT0002" }, { "OPT0005" } },
142
.driver_data = 0x0924 },
143
/* OPTi 82C925 */
144
{ .id = "OPT0925",
145
.devs = { { "OPT9250" }, { "OPT0002" }, { "OPT0005" } },
146
.driver_data = 0x0925 },
147
#else
148
/* OPTi 82C931/3 */
149
{ .id = "OPT0931", .devs = { { "OPT9310" }, { "OPT0002" } },
150
.driver_data = 0x0931 },
151
#endif /* OPTi93X */
152
{ .id = "" }
153
};
154
155
MODULE_DEVICE_TABLE(pnp_card, snd_opti9xx_pnpids);
156
157
#endif /* CONFIG_PNP */
158
159
#define DEV_NAME KBUILD_MODNAME
160
161
static const char * const snd_opti9xx_names[] = {
162
"unknown",
163
"82C928", "82C929",
164
"82C924", "82C925",
165
"82C930", "82C931", "82C933"
166
};
167
168
static int snd_opti9xx_init(struct snd_opti9xx *chip,
169
unsigned short hardware)
170
{
171
static const int opti9xx_mc_size[] = {7, 7, 10, 10, 2, 2, 2};
172
173
chip->hardware = hardware;
174
strscpy(chip->name, snd_opti9xx_names[hardware]);
175
176
spin_lock_init(&chip->lock);
177
178
chip->irq = -1;
179
180
#ifndef OPTi93X
181
#ifdef CONFIG_PNP
182
if (isapnp && chip->mc_base)
183
/* PnP resource gives the least 10 bits */
184
chip->mc_base |= 0xc00;
185
else
186
#endif /* CONFIG_PNP */
187
{
188
chip->mc_base = 0xf8c;
189
chip->mc_base_size = opti9xx_mc_size[hardware];
190
}
191
#else
192
chip->mc_base_size = opti9xx_mc_size[hardware];
193
#endif
194
195
switch (hardware) {
196
#ifndef OPTi93X
197
case OPTi9XX_HW_82C928:
198
case OPTi9XX_HW_82C929:
199
chip->password = (hardware == OPTi9XX_HW_82C928) ? 0xe2 : 0xe3;
200
chip->pwd_reg = 3;
201
break;
202
203
case OPTi9XX_HW_82C924:
204
case OPTi9XX_HW_82C925:
205
chip->password = 0xe5;
206
chip->pwd_reg = 3;
207
break;
208
#else /* OPTi93X */
209
210
case OPTi9XX_HW_82C930:
211
case OPTi9XX_HW_82C931:
212
case OPTi9XX_HW_82C933:
213
chip->mc_base = (hardware == OPTi9XX_HW_82C930) ? 0xf8f : 0xf8d;
214
if (!chip->mc_indir_index)
215
chip->mc_indir_index = 0xe0e;
216
chip->password = 0xe4;
217
chip->pwd_reg = 0;
218
break;
219
#endif /* OPTi93X */
220
221
default:
222
dev_err(chip->card->dev, "chip %d not supported\n", hardware);
223
return -ENODEV;
224
}
225
return 0;
226
}
227
228
static unsigned char snd_opti9xx_read(struct snd_opti9xx *chip,
229
unsigned char reg)
230
{
231
unsigned char retval = 0xff;
232
233
guard(spinlock_irqsave)(&chip->lock);
234
outb(chip->password, chip->mc_base + chip->pwd_reg);
235
236
switch (chip->hardware) {
237
#ifndef OPTi93X
238
case OPTi9XX_HW_82C924:
239
case OPTi9XX_HW_82C925:
240
if (reg > 7) {
241
outb(reg, chip->mc_base + 8);
242
outb(chip->password, chip->mc_base + chip->pwd_reg);
243
retval = inb(chip->mc_base + 9);
244
break;
245
}
246
fallthrough;
247
248
case OPTi9XX_HW_82C928:
249
case OPTi9XX_HW_82C929:
250
retval = inb(chip->mc_base + reg);
251
break;
252
#else /* OPTi93X */
253
254
case OPTi9XX_HW_82C930:
255
case OPTi9XX_HW_82C931:
256
case OPTi9XX_HW_82C933:
257
outb(reg, chip->mc_indir_index);
258
outb(chip->password, chip->mc_base + chip->pwd_reg);
259
retval = inb(chip->mc_indir_index + 1);
260
break;
261
#endif /* OPTi93X */
262
263
default:
264
dev_err(chip->card->dev, "chip %d not supported\n", chip->hardware);
265
}
266
267
return retval;
268
}
269
270
static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg,
271
unsigned char value)
272
{
273
guard(spinlock_irqsave)(&chip->lock);
274
outb(chip->password, chip->mc_base + chip->pwd_reg);
275
276
switch (chip->hardware) {
277
#ifndef OPTi93X
278
case OPTi9XX_HW_82C924:
279
case OPTi9XX_HW_82C925:
280
if (reg > 7) {
281
outb(reg, chip->mc_base + 8);
282
outb(chip->password, chip->mc_base + chip->pwd_reg);
283
outb(value, chip->mc_base + 9);
284
break;
285
}
286
fallthrough;
287
288
case OPTi9XX_HW_82C928:
289
case OPTi9XX_HW_82C929:
290
outb(value, chip->mc_base + reg);
291
break;
292
#else /* OPTi93X */
293
294
case OPTi9XX_HW_82C930:
295
case OPTi9XX_HW_82C931:
296
case OPTi9XX_HW_82C933:
297
outb(reg, chip->mc_indir_index);
298
outb(chip->password, chip->mc_base + chip->pwd_reg);
299
outb(value, chip->mc_indir_index + 1);
300
break;
301
#endif /* OPTi93X */
302
303
default:
304
dev_err(chip->card->dev, "chip %d not supported\n", chip->hardware);
305
}
306
}
307
308
309
static inline void snd_opti9xx_write_mask(struct snd_opti9xx *chip,
310
unsigned char reg, unsigned char value, unsigned char mask)
311
{
312
unsigned char oldval = snd_opti9xx_read(chip, reg);
313
314
snd_opti9xx_write(chip, reg, (oldval & ~mask) | (value & mask));
315
}
316
317
static int snd_opti9xx_configure(struct snd_opti9xx *chip,
318
long port,
319
int irq, int dma1, int dma2,
320
long mpu_port, int mpu_irq)
321
{
322
unsigned char wss_base_bits;
323
unsigned char irq_bits;
324
unsigned char dma_bits;
325
unsigned char mpu_port_bits = 0;
326
unsigned char mpu_irq_bits;
327
328
switch (chip->hardware) {
329
#ifndef OPTi93X
330
case OPTi9XX_HW_82C924:
331
/* opti 929 mode (?), OPL3 clock output, audio enable */
332
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0xf0, 0xfc);
333
/* enable wave audio */
334
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x02);
335
fallthrough;
336
337
case OPTi9XX_HW_82C925:
338
/* enable WSS mode */
339
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80);
340
/* OPL3 FM synthesis */
341
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), 0x00, 0x20);
342
/* disable Sound Blaster IRQ and DMA */
343
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0xf0, 0xff);
344
#ifdef CS4231
345
/* cs4231/4248 fix enabled */
346
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02);
347
#else
348
/* cs4231/4248 fix disabled */
349
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x00, 0x02);
350
#endif /* CS4231 */
351
break;
352
353
case OPTi9XX_HW_82C928:
354
case OPTi9XX_HW_82C929:
355
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80);
356
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), 0x00, 0x20);
357
/*
358
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0xa2, 0xae);
359
*/
360
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0x00, 0x0c);
361
#ifdef CS4231
362
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02);
363
#else
364
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x00, 0x02);
365
#endif /* CS4231 */
366
break;
367
368
#else /* OPTi93X */
369
case OPTi9XX_HW_82C931:
370
/* disable 3D sound (set GPIO1 as output, low) */
371
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(20), 0x04, 0x0c);
372
fallthrough;
373
374
case OPTi9XX_HW_82C933:
375
/*
376
* The BTC 1817DW has QS1000 wavetable which is connected
377
* to the serial digital input of the OPTI931.
378
*/
379
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(21), 0x82, 0xff);
380
/*
381
* This bit sets OPTI931 to automaticaly select FM
382
* or digital input signal.
383
*/
384
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(26), 0x01, 0x01);
385
fallthrough;
386
387
case OPTi9XX_HW_82C930:
388
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x03);
389
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0x00, 0xff);
390
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0x10 |
391
(chip->hardware == OPTi9XX_HW_82C930 ? 0x00 : 0x04),
392
0x34);
393
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x20, 0xbf);
394
break;
395
#endif /* OPTi93X */
396
397
default:
398
dev_err(chip->card->dev, "chip %d not supported\n", chip->hardware);
399
return -EINVAL;
400
}
401
402
/* PnP resource says it decodes only 10 bits of address */
403
switch (port & 0x3ff) {
404
case 0x130:
405
chip->wss_base = 0x530;
406
wss_base_bits = 0x00;
407
break;
408
case 0x204:
409
chip->wss_base = 0x604;
410
wss_base_bits = 0x03;
411
break;
412
case 0x280:
413
chip->wss_base = 0xe80;
414
wss_base_bits = 0x01;
415
break;
416
case 0x340:
417
chip->wss_base = 0xf40;
418
wss_base_bits = 0x02;
419
break;
420
default:
421
dev_warn(chip->card->dev, "WSS port 0x%lx not valid\n", port);
422
goto __skip_base;
423
}
424
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30);
425
426
__skip_base:
427
switch (irq) {
428
//#ifdef OPTi93X
429
case 5:
430
irq_bits = 0x05;
431
break;
432
//#endif /* OPTi93X */
433
case 7:
434
irq_bits = 0x01;
435
break;
436
case 9:
437
irq_bits = 0x02;
438
break;
439
case 10:
440
irq_bits = 0x03;
441
break;
442
case 11:
443
irq_bits = 0x04;
444
break;
445
default:
446
dev_warn(chip->card->dev, "WSS irq # %d not valid\n", irq);
447
goto __skip_resources;
448
}
449
450
switch (dma1) {
451
case 0:
452
dma_bits = 0x01;
453
break;
454
case 1:
455
dma_bits = 0x02;
456
break;
457
case 3:
458
dma_bits = 0x03;
459
break;
460
default:
461
dev_warn(chip->card->dev, "WSS dma1 # %d not valid\n", dma1);
462
goto __skip_resources;
463
}
464
465
#if defined(CS4231) || defined(OPTi93X)
466
if (dma1 == dma2) {
467
dev_err(chip->card->dev, "don't want to share dmas\n");
468
return -EBUSY;
469
}
470
471
switch (dma2) {
472
case 0:
473
case 1:
474
break;
475
default:
476
dev_warn(chip->card->dev, "WSS dma2 # %d not valid\n", dma2);
477
goto __skip_resources;
478
}
479
dma_bits |= 0x04;
480
#endif /* CS4231 || OPTi93X */
481
482
#ifndef OPTi93X
483
outb(irq_bits << 3 | dma_bits, chip->wss_base);
484
#else /* OPTi93X */
485
snd_opti9xx_write(chip, OPTi9XX_MC_REG(3), (irq_bits << 3 | dma_bits));
486
#endif /* OPTi93X */
487
488
__skip_resources:
489
if (chip->hardware > OPTi9XX_HW_82C928) {
490
switch (mpu_port) {
491
case 0:
492
case -1:
493
break;
494
case 0x300:
495
mpu_port_bits = 0x03;
496
break;
497
case 0x310:
498
mpu_port_bits = 0x02;
499
break;
500
case 0x320:
501
mpu_port_bits = 0x01;
502
break;
503
case 0x330:
504
mpu_port_bits = 0x00;
505
break;
506
default:
507
dev_warn(chip->card->dev,
508
"MPU-401 port 0x%lx not valid\n", mpu_port);
509
goto __skip_mpu;
510
}
511
512
switch (mpu_irq) {
513
case 5:
514
mpu_irq_bits = 0x02;
515
break;
516
case 7:
517
mpu_irq_bits = 0x03;
518
break;
519
case 9:
520
mpu_irq_bits = 0x00;
521
break;
522
case 10:
523
mpu_irq_bits = 0x01;
524
break;
525
default:
526
dev_warn(chip->card->dev, "MPU-401 irq # %d not valid\n",
527
mpu_irq);
528
goto __skip_mpu;
529
}
530
531
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6),
532
(mpu_port <= 0) ? 0x00 :
533
0x80 | mpu_port_bits << 5 | mpu_irq_bits << 3,
534
0xf8);
535
}
536
__skip_mpu:
537
538
return 0;
539
}
540
541
#ifdef OPTi93X
542
543
static const DECLARE_TLV_DB_SCALE(db_scale_5bit_3db_step, -9300, 300, 0);
544
static const DECLARE_TLV_DB_SCALE(db_scale_5bit, -4650, 150, 0);
545
static const DECLARE_TLV_DB_SCALE(db_scale_4bit_12db_max, -3300, 300, 0);
546
547
static const struct snd_kcontrol_new snd_opti93x_controls[] = {
548
WSS_DOUBLE("Master Playback Switch", 0,
549
OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1),
550
WSS_DOUBLE_TLV("Master Playback Volume", 0,
551
OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1,
552
db_scale_5bit_3db_step),
553
WSS_DOUBLE_TLV("PCM Playback Volume", 0,
554
CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 31, 1,
555
db_scale_5bit),
556
WSS_DOUBLE_TLV("FM Playback Volume", 0,
557
CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 1, 1, 15, 1,
558
db_scale_4bit_12db_max),
559
WSS_DOUBLE("Line Playback Switch", 0,
560
CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
561
WSS_DOUBLE_TLV("Line Playback Volume", 0,
562
CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 15, 1,
563
db_scale_4bit_12db_max),
564
WSS_DOUBLE("Mic Playback Switch", 0,
565
OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 7, 7, 1, 1),
566
WSS_DOUBLE_TLV("Mic Playback Volume", 0,
567
OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 1, 1, 15, 1,
568
db_scale_4bit_12db_max),
569
WSS_DOUBLE_TLV("CD Playback Volume", 0,
570
CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 1, 1, 15, 1,
571
db_scale_4bit_12db_max),
572
WSS_DOUBLE("Aux Playback Switch", 0,
573
OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 7, 7, 1, 1),
574
WSS_DOUBLE_TLV("Aux Playback Volume", 0,
575
OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 1, 1, 15, 1,
576
db_scale_4bit_12db_max),
577
};
578
579
static int snd_opti93x_mixer(struct snd_wss *chip)
580
{
581
struct snd_card *card;
582
unsigned int idx;
583
struct snd_ctl_elem_id id1, id2;
584
int err;
585
586
if (snd_BUG_ON(!chip || !chip->pcm))
587
return -EINVAL;
588
589
card = chip->card;
590
591
strscpy(card->mixername, chip->pcm->name);
592
593
memset(&id1, 0, sizeof(id1));
594
memset(&id2, 0, sizeof(id2));
595
id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
596
/* reassign AUX0 switch to CD */
597
strscpy(id1.name, "Aux Playback Switch");
598
strscpy(id2.name, "CD Playback Switch");
599
err = snd_ctl_rename_id(card, &id1, &id2);
600
if (err < 0) {
601
dev_err(card->dev, "Cannot rename opti93x control\n");
602
return err;
603
}
604
/* reassign AUX1 switch to FM */
605
strscpy(id1.name, "Aux Playback Switch"); id1.index = 1;
606
strscpy(id2.name, "FM Playback Switch");
607
err = snd_ctl_rename_id(card, &id1, &id2);
608
if (err < 0) {
609
dev_err(card->dev, "Cannot rename opti93x control\n");
610
return err;
611
}
612
/* remove AUX1 volume */
613
strscpy(id1.name, "Aux Playback Volume"); id1.index = 1;
614
snd_ctl_remove_id(card, &id1);
615
616
/* Replace WSS volume controls with OPTi93x volume controls */
617
id1.index = 0;
618
for (idx = 0; idx < ARRAY_SIZE(snd_opti93x_controls); idx++) {
619
strscpy(id1.name, snd_opti93x_controls[idx].name);
620
snd_ctl_remove_id(card, &id1);
621
622
err = snd_ctl_add(card,
623
snd_ctl_new1(&snd_opti93x_controls[idx], chip));
624
if (err < 0)
625
return err;
626
}
627
return 0;
628
}
629
630
static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id)
631
{
632
struct snd_opti9xx *chip = dev_id;
633
struct snd_wss *codec = chip->codec;
634
unsigned char status;
635
636
if (!codec)
637
return IRQ_HANDLED;
638
639
status = snd_opti9xx_read(chip, OPTi9XX_MC_REG(11));
640
if ((status & OPTi93X_IRQ_PLAYBACK) && codec->playback_substream)
641
snd_pcm_period_elapsed(codec->playback_substream);
642
if ((status & OPTi93X_IRQ_CAPTURE) && codec->capture_substream) {
643
snd_wss_overrange(codec);
644
snd_pcm_period_elapsed(codec->capture_substream);
645
}
646
outb(0x00, OPTi93X_PORT(codec, STATUS));
647
return IRQ_HANDLED;
648
}
649
650
#endif /* OPTi93X */
651
652
static int snd_opti9xx_read_check(struct snd_card *card,
653
struct snd_opti9xx *chip)
654
{
655
unsigned char value;
656
657
chip->res_mc_base =
658
devm_request_region(card->dev, chip->mc_base,
659
chip->mc_base_size, "OPTi9xx MC");
660
if (!chip->res_mc_base)
661
return -EBUSY;
662
#ifndef OPTi93X
663
value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(1));
664
if (value != 0xff && value != inb(chip->mc_base + OPTi9XX_MC_REG(1)))
665
if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1)))
666
return 0;
667
#else /* OPTi93X */
668
chip->res_mc_indir =
669
devm_request_region(card->dev, chip->mc_indir_index, 2,
670
"OPTi93x MC");
671
if (!chip->res_mc_indir)
672
return -EBUSY;
673
674
scoped_guard(spinlock_irqsave, &chip->lock) {
675
outb(chip->password, chip->mc_base + chip->pwd_reg);
676
outb(((chip->mc_indir_index & 0x1f0) >> 4), chip->mc_base);
677
}
678
679
value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(7));
680
snd_opti9xx_write(chip, OPTi9XX_MC_REG(7), 0xff - value);
681
if (snd_opti9xx_read(chip, OPTi9XX_MC_REG(7)) == 0xff - value)
682
return 0;
683
684
devm_release_resource(card->dev, chip->res_mc_indir);
685
chip->res_mc_indir = NULL;
686
#endif /* OPTi93X */
687
devm_release_resource(card->dev, chip->res_mc_base);
688
chip->res_mc_base = NULL;
689
690
return -ENODEV;
691
}
692
693
static int snd_card_opti9xx_detect(struct snd_card *card,
694
struct snd_opti9xx *chip)
695
{
696
int i, err;
697
698
#ifndef OPTi93X
699
for (i = OPTi9XX_HW_82C928; i < OPTi9XX_HW_82C930; i++) {
700
#else
701
for (i = OPTi9XX_HW_82C931; i >= OPTi9XX_HW_82C930; i--) {
702
#endif
703
err = snd_opti9xx_init(chip, i);
704
if (err < 0)
705
return err;
706
707
err = snd_opti9xx_read_check(card, chip);
708
if (err == 0)
709
return 1;
710
#ifdef OPTi93X
711
chip->mc_indir_index = 0;
712
#endif
713
}
714
return -ENODEV;
715
}
716
717
#ifdef CONFIG_PNP
718
static int snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
719
struct pnp_card_link *card,
720
const struct pnp_card_device_id *pid)
721
{
722
struct pnp_dev *pdev;
723
int err;
724
struct pnp_dev *devmpu;
725
#ifndef OPTi93X
726
struct pnp_dev *devmc;
727
#endif
728
729
pdev = pnp_request_card_device(card, pid->devs[0].id, NULL);
730
if (pdev == NULL)
731
return -EBUSY;
732
733
err = pnp_activate_dev(pdev);
734
if (err < 0) {
735
dev_err(chip->card->dev, "AUDIO pnp configure failure: %d\n", err);
736
return err;
737
}
738
739
#ifdef OPTi93X
740
port = pnp_port_start(pdev, 0) - 4;
741
fm_port = pnp_port_start(pdev, 1) + 8;
742
/* adjust mc_indir_index - some cards report it at 0xe?d,
743
other at 0xe?c but it really is always at 0xe?e */
744
chip->mc_indir_index = (pnp_port_start(pdev, 3) & ~0xf) | 0xe;
745
#else
746
devmc = pnp_request_card_device(card, pid->devs[2].id, NULL);
747
if (devmc == NULL)
748
return -EBUSY;
749
750
err = pnp_activate_dev(devmc);
751
if (err < 0) {
752
dev_err(chip->card->dev, "MC pnp configure failure: %d\n", err);
753
return err;
754
}
755
756
port = pnp_port_start(pdev, 1);
757
fm_port = pnp_port_start(pdev, 2) + 8;
758
/*
759
* The MC(0) is never accessed and card does not
760
* include it in the PnP resource range. OPTI93x include it.
761
*/
762
chip->mc_base = pnp_port_start(devmc, 0) - 1;
763
chip->mc_base_size = pnp_port_len(devmc, 0) + 1;
764
#endif /* OPTi93X */
765
irq = pnp_irq(pdev, 0);
766
dma1 = pnp_dma(pdev, 0);
767
#if defined(CS4231) || defined(OPTi93X)
768
dma2 = pnp_dma(pdev, 1);
769
#endif /* CS4231 || OPTi93X */
770
771
devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL);
772
773
if (devmpu && mpu_port > 0) {
774
err = pnp_activate_dev(devmpu);
775
if (err < 0) {
776
dev_err(chip->card->dev, "MPU401 pnp configure failure\n");
777
mpu_port = -1;
778
} else {
779
mpu_port = pnp_port_start(devmpu, 0);
780
mpu_irq = pnp_irq(devmpu, 0);
781
}
782
}
783
return pid->driver_data;
784
}
785
#endif /* CONFIG_PNP */
786
787
static int snd_opti9xx_probe(struct snd_card *card)
788
{
789
static const long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
790
int error;
791
int xdma2;
792
struct snd_opti9xx *chip = card->private_data;
793
struct snd_wss *codec;
794
struct snd_rawmidi *rmidi;
795
struct snd_hwdep *synth;
796
797
#if defined(CS4231) || defined(OPTi93X)
798
xdma2 = dma2;
799
#else
800
xdma2 = -1;
801
#endif
802
803
if (port == SNDRV_AUTO_PORT) {
804
port = snd_legacy_find_free_ioport(possible_ports, 4);
805
if (port < 0) {
806
dev_err(card->dev, "unable to find a free WSS port\n");
807
return -EBUSY;
808
}
809
}
810
error = snd_opti9xx_configure(chip, port, irq, dma1, xdma2,
811
mpu_port, mpu_irq);
812
if (error)
813
return error;
814
815
error = snd_wss_create(card, chip->wss_base + 4, -1, irq, dma1, xdma2,
816
#ifdef OPTi93X
817
WSS_HW_OPTI93X, WSS_HWSHARE_IRQ,
818
#else
819
WSS_HW_DETECT, 0,
820
#endif
821
&codec);
822
if (error < 0)
823
return error;
824
chip->codec = codec;
825
error = snd_wss_pcm(codec, 0);
826
if (error < 0)
827
return error;
828
error = snd_wss_mixer(codec);
829
if (error < 0)
830
return error;
831
#ifdef OPTi93X
832
error = snd_opti93x_mixer(codec);
833
if (error < 0)
834
return error;
835
#endif
836
#ifdef CS4231
837
error = snd_wss_timer(codec, 0);
838
if (error < 0)
839
return error;
840
#endif
841
#ifdef OPTi93X
842
error = devm_request_irq(card->dev, irq, snd_opti93x_interrupt,
843
0, DEV_NAME" - WSS", chip);
844
if (error < 0) {
845
dev_err(card->dev, "opti9xx: can't grab IRQ %d\n", irq);
846
return error;
847
}
848
#endif
849
chip->irq = irq;
850
card->sync_irq = chip->irq;
851
strscpy(card->driver, chip->name);
852
sprintf(card->shortname, "OPTi %s", card->driver);
853
#if defined(CS4231) || defined(OPTi93X)
854
scnprintf(card->longname, sizeof(card->longname),
855
"%s, %s at 0x%lx, irq %d, dma %d&%d",
856
card->shortname, codec->pcm->name,
857
chip->wss_base + 4, irq, dma1, xdma2);
858
#else
859
scnprintf(card->longname, sizeof(card->longname),
860
"%s, %s at 0x%lx, irq %d, dma %d",
861
card->shortname, codec->pcm->name, chip->wss_base + 4, irq,
862
dma1);
863
#endif /* CS4231 || OPTi93X */
864
865
if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT)
866
rmidi = NULL;
867
else {
868
error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
869
mpu_port, 0, mpu_irq, &rmidi);
870
if (error)
871
dev_warn(card->dev, "no MPU-401 device at 0x%lx?\n",
872
mpu_port);
873
}
874
875
if (fm_port > 0 && fm_port != SNDRV_AUTO_PORT) {
876
struct snd_opl3 *opl3 = NULL;
877
#ifndef OPTi93X
878
if (chip->hardware == OPTi9XX_HW_82C928 ||
879
chip->hardware == OPTi9XX_HW_82C929 ||
880
chip->hardware == OPTi9XX_HW_82C924) {
881
struct snd_opl4 *opl4;
882
/* assume we have an OPL4 */
883
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2),
884
0x20, 0x20);
885
if (snd_opl4_create(card, fm_port, fm_port - 8,
886
2, &opl3, &opl4) < 0) {
887
/* no luck, use OPL3 instead */
888
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2),
889
0x00, 0x20);
890
}
891
}
892
#endif /* !OPTi93X */
893
if (!opl3 && snd_opl3_create(card, fm_port, fm_port + 2,
894
OPL3_HW_AUTO, 0, &opl3) < 0) {
895
dev_warn(card->dev, "no OPL device at 0x%lx-0x%lx\n",
896
fm_port, fm_port + 4 - 1);
897
}
898
if (opl3) {
899
error = snd_opl3_hwdep_new(opl3, 0, 1, &synth);
900
if (error < 0)
901
return error;
902
}
903
}
904
905
return snd_card_register(card);
906
}
907
908
static int snd_opti9xx_card_new(struct device *pdev, struct snd_card **cardp)
909
{
910
struct snd_card *card;
911
int err;
912
913
err = snd_devm_card_new(pdev, index, id, THIS_MODULE,
914
sizeof(struct snd_opti9xx), &card);
915
if (err < 0)
916
return err;
917
*cardp = card;
918
return 0;
919
}
920
921
static int snd_opti9xx_isa_match(struct device *devptr,
922
unsigned int dev)
923
{
924
#ifdef CONFIG_PNP
925
if (snd_opti9xx_pnp_is_probed)
926
return 0;
927
if (isapnp)
928
return 0;
929
#endif
930
return 1;
931
}
932
933
static int snd_opti9xx_isa_probe(struct device *devptr,
934
unsigned int dev)
935
{
936
struct snd_card *card;
937
int error;
938
static const long possible_mpu_ports[] = {0x300, 0x310, 0x320, 0x330, -1};
939
#ifdef OPTi93X
940
static const int possible_irqs[] = {5, 9, 10, 11, 7, -1};
941
#else
942
static const int possible_irqs[] = {9, 10, 11, 7, -1};
943
#endif /* OPTi93X */
944
static const int possible_mpu_irqs[] = {5, 9, 10, 7, -1};
945
static const int possible_dma1s[] = {3, 1, 0, -1};
946
#if defined(CS4231) || defined(OPTi93X)
947
static const int possible_dma2s[][2] = {{1,-1}, {0,-1}, {-1,-1}, {0,-1}};
948
#endif /* CS4231 || OPTi93X */
949
950
if (mpu_port == SNDRV_AUTO_PORT) {
951
mpu_port = snd_legacy_find_free_ioport(possible_mpu_ports, 2);
952
if (mpu_port < 0) {
953
dev_err(devptr, "unable to find a free MPU401 port\n");
954
return -EBUSY;
955
}
956
}
957
if (irq == SNDRV_AUTO_IRQ) {
958
irq = snd_legacy_find_free_irq(possible_irqs);
959
if (irq < 0) {
960
dev_err(devptr, "unable to find a free IRQ\n");
961
return -EBUSY;
962
}
963
}
964
if (mpu_irq == SNDRV_AUTO_IRQ) {
965
mpu_irq = snd_legacy_find_free_irq(possible_mpu_irqs);
966
if (mpu_irq < 0) {
967
dev_err(devptr, "unable to find a free MPU401 IRQ\n");
968
return -EBUSY;
969
}
970
}
971
if (dma1 == SNDRV_AUTO_DMA) {
972
dma1 = snd_legacy_find_free_dma(possible_dma1s);
973
if (dma1 < 0) {
974
dev_err(devptr, "unable to find a free DMA1\n");
975
return -EBUSY;
976
}
977
}
978
#if defined(CS4231) || defined(OPTi93X)
979
if (dma2 == SNDRV_AUTO_DMA) {
980
dma2 = snd_legacy_find_free_dma(possible_dma2s[dma1 % 4]);
981
if (dma2 < 0) {
982
dev_err(devptr, "unable to find a free DMA2\n");
983
return -EBUSY;
984
}
985
}
986
#endif
987
988
error = snd_opti9xx_card_new(devptr, &card);
989
if (error < 0)
990
return error;
991
992
error = snd_card_opti9xx_detect(card, card->private_data);
993
if (error < 0)
994
return error;
995
error = snd_opti9xx_probe(card);
996
if (error < 0)
997
return error;
998
dev_set_drvdata(devptr, card);
999
return 0;
1000
}
1001
1002
#ifdef CONFIG_PM
1003
static int snd_opti9xx_suspend(struct snd_card *card)
1004
{
1005
struct snd_opti9xx *chip = card->private_data;
1006
1007
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
1008
chip->codec->suspend(chip->codec);
1009
return 0;
1010
}
1011
1012
static int snd_opti9xx_resume(struct snd_card *card)
1013
{
1014
struct snd_opti9xx *chip = card->private_data;
1015
int error, xdma2;
1016
#if defined(CS4231) || defined(OPTi93X)
1017
xdma2 = dma2;
1018
#else
1019
xdma2 = -1;
1020
#endif
1021
1022
error = snd_opti9xx_configure(chip, port, irq, dma1, xdma2,
1023
mpu_port, mpu_irq);
1024
if (error)
1025
return error;
1026
chip->codec->resume(chip->codec);
1027
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1028
return 0;
1029
}
1030
1031
static int snd_opti9xx_isa_suspend(struct device *dev, unsigned int n,
1032
pm_message_t state)
1033
{
1034
return snd_opti9xx_suspend(dev_get_drvdata(dev));
1035
}
1036
1037
static int snd_opti9xx_isa_resume(struct device *dev, unsigned int n)
1038
{
1039
return snd_opti9xx_resume(dev_get_drvdata(dev));
1040
}
1041
#endif
1042
1043
static struct isa_driver snd_opti9xx_driver = {
1044
.match = snd_opti9xx_isa_match,
1045
.probe = snd_opti9xx_isa_probe,
1046
#ifdef CONFIG_PM
1047
.suspend = snd_opti9xx_isa_suspend,
1048
.resume = snd_opti9xx_isa_resume,
1049
#endif
1050
.driver = {
1051
.name = DEV_NAME
1052
},
1053
};
1054
1055
#ifdef CONFIG_PNP
1056
static int snd_opti9xx_pnp_probe(struct pnp_card_link *pcard,
1057
const struct pnp_card_device_id *pid)
1058
{
1059
struct snd_card *card;
1060
int error, hw;
1061
struct snd_opti9xx *chip;
1062
1063
if (snd_opti9xx_pnp_is_probed)
1064
return -EBUSY;
1065
if (! isapnp)
1066
return -ENODEV;
1067
error = snd_opti9xx_card_new(&pcard->card->dev, &card);
1068
if (error < 0)
1069
return error;
1070
chip = card->private_data;
1071
chip->card = card;
1072
1073
hw = snd_card_opti9xx_pnp(chip, pcard, pid);
1074
switch (hw) {
1075
case 0x0924:
1076
hw = OPTi9XX_HW_82C924;
1077
break;
1078
case 0x0925:
1079
hw = OPTi9XX_HW_82C925;
1080
break;
1081
case 0x0931:
1082
hw = OPTi9XX_HW_82C931;
1083
break;
1084
default:
1085
return -ENODEV;
1086
}
1087
1088
error = snd_opti9xx_init(chip, hw);
1089
if (error)
1090
return error;
1091
error = snd_opti9xx_read_check(card, chip);
1092
if (error) {
1093
dev_err(card->dev, "OPTI chip not found\n");
1094
return error;
1095
}
1096
error = snd_opti9xx_probe(card);
1097
if (error < 0)
1098
return error;
1099
pnp_set_card_drvdata(pcard, card);
1100
snd_opti9xx_pnp_is_probed = 1;
1101
return 0;
1102
}
1103
1104
static void snd_opti9xx_pnp_remove(struct pnp_card_link *pcard)
1105
{
1106
snd_opti9xx_pnp_is_probed = 0;
1107
}
1108
1109
#ifdef CONFIG_PM
1110
static int snd_opti9xx_pnp_suspend(struct pnp_card_link *pcard,
1111
pm_message_t state)
1112
{
1113
return snd_opti9xx_suspend(pnp_get_card_drvdata(pcard));
1114
}
1115
1116
static int snd_opti9xx_pnp_resume(struct pnp_card_link *pcard)
1117
{
1118
return snd_opti9xx_resume(pnp_get_card_drvdata(pcard));
1119
}
1120
#endif
1121
1122
static struct pnp_card_driver opti9xx_pnpc_driver = {
1123
.flags = PNP_DRIVER_RES_DISABLE,
1124
.name = DEV_NAME,
1125
.id_table = snd_opti9xx_pnpids,
1126
.probe = snd_opti9xx_pnp_probe,
1127
.remove = snd_opti9xx_pnp_remove,
1128
#ifdef CONFIG_PM
1129
.suspend = snd_opti9xx_pnp_suspend,
1130
.resume = snd_opti9xx_pnp_resume,
1131
#endif
1132
};
1133
#endif
1134
1135
#ifdef OPTi93X
1136
#define CHIP_NAME "82C93x"
1137
#else
1138
#define CHIP_NAME "82C92x"
1139
#endif
1140
1141
static int __init alsa_card_opti9xx_init(void)
1142
{
1143
#ifdef CONFIG_PNP
1144
pnp_register_card_driver(&opti9xx_pnpc_driver);
1145
if (snd_opti9xx_pnp_is_probed)
1146
return 0;
1147
pnp_unregister_card_driver(&opti9xx_pnpc_driver);
1148
#endif
1149
return isa_register_driver(&snd_opti9xx_driver, 1);
1150
}
1151
1152
static void __exit alsa_card_opti9xx_exit(void)
1153
{
1154
if (!snd_opti9xx_pnp_is_probed) {
1155
isa_unregister_driver(&snd_opti9xx_driver);
1156
return;
1157
}
1158
#ifdef CONFIG_PNP
1159
pnp_unregister_card_driver(&opti9xx_pnpc_driver);
1160
#endif
1161
}
1162
1163
module_init(alsa_card_opti9xx_init)
1164
module_exit(alsa_card_opti9xx_exit)
1165
1166