blob: b94339f8306fd29620005bad3856a6d26c1027aa [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 card-opti92x-ad1848.c - driver for OPTi 82c92x based soundcards.
3 Copyright (C) 1998-2000 by Massimo Piccioni <dafastidio@libero.it>
4
5 Part of this code was developed at the Italian Ministry of Air Defence,
6 Sixth Division (oh, che pace ...), Rome.
7
8 Thanks to Maria Grazia Pollarini, Salvatore Vassallo.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25
26#include <sound/driver.h>
27#include <asm/io.h>
28#include <asm/dma.h>
29#include <linux/delay.h>
30#include <linux/init.h>
31#include <linux/slab.h>
32#include <linux/pnp.h>
33#include <linux/moduleparam.h>
34#include <sound/core.h>
35#ifdef CS4231
36#include <sound/cs4231.h>
37#else
38#ifndef OPTi93X
39#include <sound/ad1848.h>
40#else
41#include <sound/control.h>
42#include <sound/pcm.h>
43#endif /* OPTi93X */
44#endif /* CS4231 */
45#include <sound/mpu401.h>
46#include <sound/opl3.h>
47#ifndef OPTi93X
48#include <sound/opl4.h>
49#endif
50#define SNDRV_LEGACY_FIND_FREE_IRQ
51#define SNDRV_LEGACY_FIND_FREE_DMA
52#include <sound/initval.h>
53
54MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>");
55MODULE_LICENSE("GPL");
56#ifdef OPTi93X
57MODULE_DESCRIPTION("OPTi93X");
58MODULE_SUPPORTED_DEVICE("{{OPTi,82C931/3}}");
59#else /* OPTi93X */
60#ifdef CS4231
61MODULE_DESCRIPTION("OPTi92X - CS4231");
62MODULE_SUPPORTED_DEVICE("{{OPTi,82C924 (CS4231)},"
63 "{OPTi,82C925 (CS4231)}}");
64#else /* CS4231 */
65MODULE_DESCRIPTION("OPTi92X - AD1848");
66MODULE_SUPPORTED_DEVICE("{{OPTi,82C924 (AD1848)},"
67 "{OPTi,82C925 (AD1848)},"
68 "{OAK,Mozart}}");
69#endif /* CS4231 */
70#endif /* OPTi93X */
71
72static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
73static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
74//static int enable = SNDRV_DEFAULT_ENABLE1; /* Enable this card */
75static int isapnp = 1; /* Enable ISA PnP detection */
76static long port = SNDRV_DEFAULT_PORT1; /* 0x530,0xe80,0xf40,0x604 */
77static long mpu_port = SNDRV_DEFAULT_PORT1; /* 0x300,0x310,0x320,0x330 */
78static long fm_port = SNDRV_DEFAULT_PORT1; /* 0x388 */
79static int irq = SNDRV_DEFAULT_IRQ1; /* 5,7,9,10,11 */
80static int mpu_irq = SNDRV_DEFAULT_IRQ1; /* 5,7,9,10 */
81static int dma1 = SNDRV_DEFAULT_DMA1; /* 0,1,3 */
82#if defined(CS4231) || defined(OPTi93X)
83static int dma2 = SNDRV_DEFAULT_DMA1; /* 0,1,3 */
84#endif /* CS4231 || OPTi93X */
85
86module_param(index, int, 0444);
87MODULE_PARM_DESC(index, "Index value for opti9xx based soundcard.");
88module_param(id, charp, 0444);
89MODULE_PARM_DESC(id, "ID string for opti9xx based soundcard.");
90//module_param(enable, bool, 0444);
91//MODULE_PARM_DESC(enable, "Enable opti9xx soundcard.");
92module_param(isapnp, bool, 0444);
93MODULE_PARM_DESC(isapnp, "Enable ISA PnP detection for specified soundcard.");
94module_param(port, long, 0444);
95MODULE_PARM_DESC(port, "WSS port # for opti9xx driver.");
96module_param(mpu_port, long, 0444);
97MODULE_PARM_DESC(mpu_port, "MPU-401 port # for opti9xx driver.");
98module_param(fm_port, long, 0444);
99MODULE_PARM_DESC(fm_port, "FM port # for opti9xx driver.");
100module_param(irq, int, 0444);
101MODULE_PARM_DESC(irq, "WSS irq # for opti9xx driver.");
102module_param(mpu_irq, int, 0444);
103MODULE_PARM_DESC(mpu_irq, "MPU-401 irq # for opti9xx driver.");
104module_param(dma1, int, 0444);
105MODULE_PARM_DESC(dma1, "1st dma # for opti9xx driver.");
106#if defined(CS4231) || defined(OPTi93X)
107module_param(dma2, int, 0444);
108MODULE_PARM_DESC(dma2, "2nd dma # for opti9xx driver.");
109#endif /* CS4231 || OPTi93X */
110
111#define OPTi9XX_HW_DETECT 0
112#define OPTi9XX_HW_82C928 1
113#define OPTi9XX_HW_82C929 2
114#define OPTi9XX_HW_82C924 3
115#define OPTi9XX_HW_82C925 4
116#define OPTi9XX_HW_82C930 5
117#define OPTi9XX_HW_82C931 6
118#define OPTi9XX_HW_82C933 7
119#define OPTi9XX_HW_LAST OPTi9XX_HW_82C933
120
121#define OPTi9XX_MC_REG(n) n
122
123typedef struct _snd_opti9xx opti9xx_t;
124
125#ifdef OPTi93X
126
127#define OPTi93X_INDEX 0x00
128#define OPTi93X_DATA 0x01
129#define OPTi93X_STATUS 0x02
130#define OPTi93X_DDATA 0x03
131#define OPTi93X_PORT(chip, r) ((chip)->port + OPTi93X_##r)
132
133#define OPTi93X_MIXOUT_LEFT 0x00
134#define OPTi93X_MIXOUT_RIGHT 0x01
135#define OPTi93X_CD_LEFT_INPUT 0x02
136#define OPTi93X_CD_RIGHT_INPUT 0x03
137#define OPTi930_AUX_LEFT_INPUT 0x04
138#define OPTi930_AUX_RIGHT_INPUT 0x05
139#define OPTi931_FM_LEFT_INPUT 0x04
140#define OPTi931_FM_RIGHT_INPUT 0x05
141#define OPTi93X_DAC_LEFT 0x06
142#define OPTi93X_DAC_RIGHT 0x07
143#define OPTi93X_PLAY_FORMAT 0x08
144#define OPTi93X_IFACE_CONF 0x09
145#define OPTi93X_PIN_CTRL 0x0a
146#define OPTi93X_ERR_INIT 0x0b
147#define OPTi93X_ID 0x0c
148#define OPTi93X_PLAY_UPR_CNT 0x0e
149#define OPTi93X_PLAY_LWR_CNT 0x0f
150#define OPTi931_AUX_LEFT_INPUT 0x10
151#define OPTi931_AUX_RIGHT_INPUT 0x11
152#define OPTi93X_LINE_LEFT_INPUT 0x12
153#define OPTi93X_LINE_RIGHT_INPUT 0x13
154#define OPTi93X_MIC_LEFT_INPUT 0x14
155#define OPTi93X_MIC_RIGHT_INPUT 0x15
156#define OPTi93X_OUT_LEFT 0x16
157#define OPTi93X_OUT_RIGHT 0x17
158#define OPTi93X_CAPT_FORMAT 0x1c
159#define OPTi93X_CAPT_UPR_CNT 0x1e
160#define OPTi93X_CAPT_LWR_CNT 0x1f
161
162#define OPTi93X_TRD 0x20
163#define OPTi93X_MCE 0x40
164#define OPTi93X_INIT 0x80
165
166#define OPTi93X_MIXOUT_MIC_GAIN 0x20
167#define OPTi93X_MIXOUT_LINE 0x00
168#define OPTi93X_MIXOUT_CD 0x40
169#define OPTi93X_MIXOUT_MIC 0x80
170#define OPTi93X_MIXOUT_MIXER 0xc0
171
172#define OPTi93X_STEREO 0x10
173#define OPTi93X_LINEAR_8 0x00
174#define OPTi93X_ULAW_8 0x20
175#define OPTi93X_LINEAR_16_LIT 0x40
176#define OPTi93X_ALAW_8 0x60
177#define OPTi93X_ADPCM_16 0xa0
178#define OPTi93X_LINEAR_16_BIG 0xc0
179
180#define OPTi93X_CAPTURE_PIO 0x80
181#define OPTi93X_PLAYBACK_PIO 0x40
182#define OPTi93X_AUTOCALIB 0x08
183#define OPTi93X_SINGLE_DMA 0x04
184#define OPTi93X_CAPTURE_ENABLE 0x02
185#define OPTi93X_PLAYBACK_ENABLE 0x01
186
187#define OPTi93X_IRQ_ENABLE 0x02
188
189#define OPTi93X_DMA_REQUEST 0x10
190#define OPTi93X_CALIB_IN_PROGRESS 0x20
191
192#define OPTi93X_IRQ_PLAYBACK 0x04
193#define OPTi93X_IRQ_CAPTURE 0x08
194
195
196typedef struct _snd_opti93x opti93x_t;
197
198struct _snd_opti93x {
199 unsigned long port;
200 struct resource *res_port;
201 int irq;
202 int dma1;
203 int dma2;
204
205 opti9xx_t *chip;
206 unsigned short hardware;
207 unsigned char image[32];
208
209 unsigned char mce_bit;
210 unsigned short mode;
211 int mute;
212
213 spinlock_t lock;
214
215 snd_card_t *card;
216 snd_pcm_t *pcm;
217 snd_pcm_substream_t *playback_substream;
218 snd_pcm_substream_t *capture_substream;
219 unsigned int p_dma_size;
220 unsigned int c_dma_size;
221};
222
223#define OPTi93X_MODE_NONE 0x00
224#define OPTi93X_MODE_PLAY 0x01
225#define OPTi93X_MODE_CAPTURE 0x02
226#define OPTi93X_MODE_OPEN (OPTi93X_MODE_PLAY | OPTi93X_MODE_CAPTURE)
227
228#endif /* OPTi93X */
229
230struct _snd_opti9xx {
231 unsigned short hardware;
232 unsigned char password;
233 char name[7];
234
235 unsigned long mc_base;
236 struct resource *res_mc_base;
237 unsigned long mc_base_size;
238#ifdef OPTi93X
239 unsigned long mc_indir_index;
240#endif /* OPTi93X */
241 unsigned long pwd_reg;
242
243 spinlock_t lock;
244
245 long wss_base;
246 int irq;
247 int dma1;
248#if defined(CS4231) || defined(OPTi93X)
249 int dma2;
250#endif /* CS4231 || OPTi93X */
251
252 long fm_port;
253
254 long mpu_port;
255 int mpu_irq;
256
257#ifdef CONFIG_PNP
258 struct pnp_dev *dev;
259 struct pnp_dev *devmpu;
260#endif /* CONFIG_PNP */
261};
262
263static int snd_opti9xx_first_hit = 1;
264static snd_card_t *snd_opti9xx_legacy = SNDRV_DEFAULT_PTR1;
265
266#ifdef CONFIG_PNP
267
268static struct pnp_card_device_id snd_opti9xx_pnpids[] = {
269#ifndef OPTi93X
270 /* OPTi 82C924 */
271 { .id = "OPT0924", .devs = { { "OPT0000" }, { "OPT0002" } }, .driver_data = 0x0924 },
272 /* OPTi 82C925 */
273 { .id = "OPT0925", .devs = { { "OPT9250" }, { "OPT0002" } }, .driver_data = 0x0925 },
274#else
275 /* OPTi 82C931/3 */
276 { .id = "OPT0931", .devs = { { "OPT9310" }, { "OPT0002" } }, .driver_data = 0x0931 },
277#endif /* OPTi93X */
278 { .id = "" }
279};
280
281MODULE_DEVICE_TABLE(pnp_card, snd_opti9xx_pnpids);
282
283#endif /* CONFIG_PNP */
284
285#ifdef OPTi93X
286#define DRIVER_NAME "snd-card-opti93x"
287#else
288#define DRIVER_NAME "snd-card-opti92x"
289#endif /* OPTi93X */
290
291static char * snd_opti9xx_names[] = {
292 "unkown",
293 "82C928", "82C929",
294 "82C924", "82C925",
295 "82C930", "82C931", "82C933"
296};
297
298
299static long snd_legacy_find_free_ioport(long *port_table, long size)
300{
301 while (*port_table != -1) {
Takashi Iwaib1d57762005-10-10 11:56:31 +0200302 if (request_region(*port_table, size, "ALSA test")) {
303 release_region(*port_table, size);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700304 return *port_table;
305 }
306 port_table++;
307 }
308 return -1;
309}
310
311static int __devinit snd_opti9xx_init(opti9xx_t *chip, unsigned short hardware)
312{
313 static int opti9xx_mc_size[] = {7, 7, 10, 10, 2, 2, 2};
314
315 chip->hardware = hardware;
316 strcpy(chip->name, snd_opti9xx_names[hardware]);
317
318 chip->mc_base_size = opti9xx_mc_size[hardware];
319
320 spin_lock_init(&chip->lock);
321
322 chip->wss_base = -1;
323 chip->irq = -1;
324 chip->dma1 = -1;
325#if defined(CS4231) || defined (OPTi93X)
326 chip->dma2 = -1;
327#endif /* CS4231 || OPTi93X */
328 chip->fm_port = -1;
329 chip->mpu_port = -1;
330 chip->mpu_irq = -1;
331
332 switch (hardware) {
333#ifndef OPTi93X
334 case OPTi9XX_HW_82C928:
335 case OPTi9XX_HW_82C929:
336 chip->mc_base = 0xf8c;
337 chip->password = (hardware == OPTi9XX_HW_82C928) ? 0xe2 : 0xe3;
338 chip->pwd_reg = 3;
339 break;
340
341 case OPTi9XX_HW_82C924:
342 case OPTi9XX_HW_82C925:
343 chip->mc_base = 0xf8c;
344 chip->password = 0xe5;
345 chip->pwd_reg = 3;
346 break;
347#else /* OPTi93X */
348
349 case OPTi9XX_HW_82C930:
350 case OPTi9XX_HW_82C931:
351 case OPTi9XX_HW_82C933:
352 chip->mc_base = (hardware == OPTi9XX_HW_82C930) ? 0xf8f : 0xf8d;
353 chip->mc_indir_index = 0xe0e;
354 chip->password = 0xe4;
355 chip->pwd_reg = 0;
356 break;
357#endif /* OPTi93X */
358
359 default:
360 snd_printk("chip %d not supported\n", hardware);
361 return -ENODEV;
362 }
363 return 0;
364}
365
366static unsigned char snd_opti9xx_read(opti9xx_t *chip,
367 unsigned char reg)
368{
369 unsigned long flags;
370 unsigned char retval = 0xff;
371
372 spin_lock_irqsave(&chip->lock, flags);
373 outb(chip->password, chip->mc_base + chip->pwd_reg);
374
375 switch (chip->hardware) {
376#ifndef OPTi93X
377 case OPTi9XX_HW_82C924:
378 case OPTi9XX_HW_82C925:
379 if (reg > 7) {
380 outb(reg, chip->mc_base + 8);
381 outb(chip->password, chip->mc_base + chip->pwd_reg);
382 retval = inb(chip->mc_base + 9);
383 break;
384 }
385
386 case OPTi9XX_HW_82C928:
387 case OPTi9XX_HW_82C929:
388 retval = inb(chip->mc_base + reg);
389 break;
390#else /* OPTi93X */
391
392 case OPTi9XX_HW_82C930:
393 case OPTi9XX_HW_82C931:
394 case OPTi9XX_HW_82C933:
395 outb(reg, chip->mc_indir_index);
396 outb(chip->password, chip->mc_base + chip->pwd_reg);
397 retval = inb(chip->mc_indir_index + 1);
398 break;
399#endif /* OPTi93X */
400
401 default:
402 snd_printk("chip %d not supported\n", chip->hardware);
403 }
404
405 spin_unlock_irqrestore(&chip->lock, flags);
406 return retval;
407}
408
409static void snd_opti9xx_write(opti9xx_t *chip, unsigned char reg,
410 unsigned char value)
411{
412 unsigned long flags;
413
414 spin_lock_irqsave(&chip->lock, flags);
415 outb(chip->password, chip->mc_base + chip->pwd_reg);
416
417 switch (chip->hardware) {
418#ifndef OPTi93X
419 case OPTi9XX_HW_82C924:
420 case OPTi9XX_HW_82C925:
421 if (reg > 7) {
422 outb(reg, chip->mc_base + 8);
423 outb(chip->password, chip->mc_base + chip->pwd_reg);
424 outb(value, chip->mc_base + 9);
425 break;
426 }
427
428 case OPTi9XX_HW_82C928:
429 case OPTi9XX_HW_82C929:
430 outb(value, chip->mc_base + reg);
431 break;
432#else /* OPTi93X */
433
434 case OPTi9XX_HW_82C930:
435 case OPTi9XX_HW_82C931:
436 case OPTi9XX_HW_82C933:
437 outb(reg, chip->mc_indir_index);
438 outb(chip->password, chip->mc_base + chip->pwd_reg);
439 outb(value, chip->mc_indir_index + 1);
440 break;
441#endif /* OPTi93X */
442
443 default:
444 snd_printk("chip %d not supported\n", chip->hardware);
445 }
446
447 spin_unlock_irqrestore(&chip->lock, flags);
448}
449
450
451#define snd_opti9xx_write_mask(chip, reg, value, mask) \
452 snd_opti9xx_write(chip, reg, \
453 (snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask)))
454
455
456static int __devinit snd_opti9xx_configure(opti9xx_t *chip)
457{
458 unsigned char wss_base_bits;
459 unsigned char irq_bits;
460 unsigned char dma_bits;
461 unsigned char mpu_port_bits = 0;
462 unsigned char mpu_irq_bits;
463
464 switch (chip->hardware) {
465#ifndef OPTi93X
466 case OPTi9XX_HW_82C924:
467 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0xf0, 0xfc);
468 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x02);
469
470 case OPTi9XX_HW_82C925:
471 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80);
472 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), 0x00, 0x20);
473 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0xf0, 0xff);
474#ifdef CS4231
475 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02);
476#else
477 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x00, 0x02);
478#endif /* CS4231 */
479 break;
480
481 case OPTi9XX_HW_82C928:
482 case OPTi9XX_HW_82C929:
483 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80);
484 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), 0x00, 0x20);
485 /*
486 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0xa2, 0xae);
487 */
488 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0x00, 0x0c);
489#ifdef CS4231
490 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02);
491#else
492 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x00, 0x02);
493#endif /* CS4231 */
494 break;
495
496#else /* OPTi93X */
497 case OPTi9XX_HW_82C930:
498 case OPTi9XX_HW_82C931:
499 case OPTi9XX_HW_82C933:
500 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x03);
501 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0x00, 0xff);
502 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0x10 |
503 (chip->hardware == OPTi9XX_HW_82C930 ? 0x00 : 0x04),
504 0x34);
505 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x20, 0xbf);
506 break;
507#endif /* OPTi93X */
508
509 default:
510 snd_printk("chip %d not supported\n", chip->hardware);
511 return -EINVAL;
512 }
513
514 switch (chip->wss_base) {
515 case 0x530:
516 wss_base_bits = 0x00;
517 break;
518 case 0x604:
519 wss_base_bits = 0x03;
520 break;
521 case 0xe80:
522 wss_base_bits = 0x01;
523 break;
524 case 0xf40:
525 wss_base_bits = 0x02;
526 break;
527 default:
528 snd_printk("WSS port 0x%lx not valid\n", chip->wss_base);
529 goto __skip_base;
530 }
531 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30);
532
533__skip_base:
534 switch (chip->irq) {
535//#ifdef OPTi93X
536 case 5:
537 irq_bits = 0x05;
538 break;
539//#endif /* OPTi93X */
540 case 7:
541 irq_bits = 0x01;
542 break;
543 case 9:
544 irq_bits = 0x02;
545 break;
546 case 10:
547 irq_bits = 0x03;
548 break;
549 case 11:
550 irq_bits = 0x04;
551 break;
552 default:
553 snd_printk("WSS irq # %d not valid\n", chip->irq);
554 goto __skip_resources;
555 }
556
557 switch (chip->dma1) {
558 case 0:
559 dma_bits = 0x01;
560 break;
561 case 1:
562 dma_bits = 0x02;
563 break;
564 case 3:
565 dma_bits = 0x03;
566 break;
567 default:
568 snd_printk("WSS dma1 # %d not valid\n", chip->dma1);
569 goto __skip_resources;
570 }
571
572#if defined(CS4231) || defined(OPTi93X)
573 if (chip->dma1 == chip->dma2) {
574 snd_printk("don't want to share dmas\n");
575 return -EBUSY;
576 }
577
578 switch (chip->dma2) {
579 case 0:
580 case 1:
581 break;
582 default:
583 snd_printk("WSS dma2 # %d not valid\n", chip->dma2);
584 goto __skip_resources;
585 }
586 dma_bits |= 0x04;
587#endif /* CS4231 || OPTi93X */
588
589#ifndef OPTi93X
590 outb(irq_bits << 3 | dma_bits, chip->wss_base);
591#else /* OPTi93X */
592 snd_opti9xx_write(chip, OPTi9XX_MC_REG(3), (irq_bits << 3 | dma_bits));
593#endif /* OPTi93X */
594
595__skip_resources:
596 if (chip->hardware > OPTi9XX_HW_82C928) {
597 switch (chip->mpu_port) {
598 case 0:
599 case -1:
600 break;
601 case 0x300:
602 mpu_port_bits = 0x03;
603 break;
604 case 0x310:
605 mpu_port_bits = 0x02;
606 break;
607 case 0x320:
608 mpu_port_bits = 0x01;
609 break;
610 case 0x330:
611 mpu_port_bits = 0x00;
612 break;
613 default:
614 snd_printk("MPU-401 port 0x%lx not valid\n",
615 chip->mpu_port);
616 goto __skip_mpu;
617 }
618
619 switch (chip->mpu_irq) {
620 case 5:
621 mpu_irq_bits = 0x02;
622 break;
623 case 7:
624 mpu_irq_bits = 0x03;
625 break;
626 case 9:
627 mpu_irq_bits = 0x00;
628 break;
629 case 10:
630 mpu_irq_bits = 0x01;
631 break;
632 default:
633 snd_printk("MPU-401 irq # %d not valid\n",
634 chip->mpu_irq);
635 goto __skip_mpu;
636 }
637
638 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6),
639 (chip->mpu_port <= 0) ? 0x00 :
640 0x80 | mpu_port_bits << 5 | mpu_irq_bits << 3,
641 0xf8);
642 }
643__skip_mpu:
644
645 return 0;
646}
647
648#ifdef OPTi93X
649
650static unsigned char snd_opti93x_default_image[32] =
651{
652 0x00, /* 00/00 - l_mixout_outctrl */
653 0x00, /* 01/01 - r_mixout_outctrl */
654 0x88, /* 02/02 - l_cd_inctrl */
655 0x88, /* 03/03 - r_cd_inctrl */
656 0x88, /* 04/04 - l_a1/fm_inctrl */
657 0x88, /* 05/05 - r_a1/fm_inctrl */
658 0x80, /* 06/06 - l_dac_inctrl */
659 0x80, /* 07/07 - r_dac_inctrl */
660 0x00, /* 08/08 - ply_dataform_reg */
661 0x00, /* 09/09 - if_conf */
662 0x00, /* 0a/10 - pin_ctrl */
663 0x00, /* 0b/11 - err_init_reg */
664 0x0a, /* 0c/12 - id_reg */
665 0x00, /* 0d/13 - reserved */
666 0x00, /* 0e/14 - ply_upcount_reg */
667 0x00, /* 0f/15 - ply_lowcount_reg */
668 0x88, /* 10/16 - reserved/l_a1_inctrl */
669 0x88, /* 11/17 - reserved/r_a1_inctrl */
670 0x88, /* 12/18 - l_line_inctrl */
671 0x88, /* 13/19 - r_line_inctrl */
672 0x88, /* 14/20 - l_mic_inctrl */
673 0x88, /* 15/21 - r_mic_inctrl */
674 0x80, /* 16/22 - l_out_outctrl */
675 0x80, /* 17/23 - r_out_outctrl */
676 0x00, /* 18/24 - reserved */
677 0x00, /* 19/25 - reserved */
678 0x00, /* 1a/26 - reserved */
679 0x00, /* 1b/27 - reserved */
680 0x00, /* 1c/28 - cap_dataform_reg */
681 0x00, /* 1d/29 - reserved */
682 0x00, /* 1e/30 - cap_upcount_reg */
683 0x00 /* 1f/31 - cap_lowcount_reg */
684};
685
686
687static int snd_opti93x_busy_wait(opti93x_t *chip)
688{
689 int timeout;
690
691 for (timeout = 250; timeout-- > 0; udelay(10))
692 if (!(inb(OPTi93X_PORT(chip, INDEX)) & OPTi93X_INIT))
693 return 0;
694
695 snd_printk("chip still busy.\n");
696 return -EBUSY;
697}
698
699static unsigned char snd_opti93x_in(opti93x_t *chip, unsigned char reg)
700{
701 snd_opti93x_busy_wait(chip);
702 outb(chip->mce_bit | (reg & 0x1f), OPTi93X_PORT(chip, INDEX));
703 return inb(OPTi93X_PORT(chip, DATA));
704}
705
706static void snd_opti93x_out(opti93x_t *chip, unsigned char reg,
707 unsigned char value)
708{
709 snd_opti93x_busy_wait(chip);
710 outb(chip->mce_bit | (reg & 0x1f), OPTi93X_PORT(chip, INDEX));
711 outb(value, OPTi93X_PORT(chip, DATA));
712}
713
714static void snd_opti93x_out_image(opti93x_t *chip, unsigned char reg,
715 unsigned char value)
716{
717 snd_opti93x_out(chip, reg, chip->image[reg] = value);
718}
719
720static void snd_opti93x_out_mask(opti93x_t *chip, unsigned char reg,
721 unsigned char mask, unsigned char value)
722{
723 snd_opti93x_out_image(chip, reg,
724 (chip->image[reg] & ~mask) | (value & mask));
725}
726
727
728static void snd_opti93x_mce_up(opti93x_t *chip)
729{
730 snd_opti93x_busy_wait(chip);
731
732 chip->mce_bit = OPTi93X_MCE;
733 if (!(inb(OPTi93X_PORT(chip, INDEX)) & OPTi93X_MCE))
734 outb(chip->mce_bit, OPTi93X_PORT(chip, INDEX));
735}
736
737static void snd_opti93x_mce_down(opti93x_t *chip)
738{
739 snd_opti93x_busy_wait(chip);
740
741 chip->mce_bit = 0;
742 if (inb(OPTi93X_PORT(chip, INDEX)) & OPTi93X_MCE)
743 outb(chip->mce_bit, OPTi93X_PORT(chip, INDEX));
744}
745
746#define snd_opti93x_mute_reg(chip, reg, mute) \
747 snd_opti93x_out(chip, reg, mute ? 0x80 : chip->image[reg]);
748
749static void snd_opti93x_mute(opti93x_t *chip, int mute)
750{
751 mute = mute ? 1 : 0;
752 if (chip->mute == mute)
753 return;
754
755 chip->mute = mute;
756
757 snd_opti93x_mute_reg(chip, OPTi93X_CD_LEFT_INPUT, mute);
758 snd_opti93x_mute_reg(chip, OPTi93X_CD_RIGHT_INPUT, mute);
759 switch (chip->hardware) {
760 case OPTi9XX_HW_82C930:
761 snd_opti93x_mute_reg(chip, OPTi930_AUX_LEFT_INPUT, mute);
762 snd_opti93x_mute_reg(chip, OPTi930_AUX_RIGHT_INPUT, mute);
763 break;
764 case OPTi9XX_HW_82C931:
765 case OPTi9XX_HW_82C933:
766 snd_opti93x_mute_reg(chip, OPTi931_FM_LEFT_INPUT, mute);
767 snd_opti93x_mute_reg(chip, OPTi931_FM_RIGHT_INPUT, mute);
768 snd_opti93x_mute_reg(chip, OPTi931_AUX_LEFT_INPUT, mute);
769 snd_opti93x_mute_reg(chip, OPTi931_AUX_RIGHT_INPUT, mute);
770 }
771 snd_opti93x_mute_reg(chip, OPTi93X_DAC_LEFT, mute);
772 snd_opti93x_mute_reg(chip, OPTi93X_DAC_RIGHT, mute);
773 snd_opti93x_mute_reg(chip, OPTi93X_LINE_LEFT_INPUT, mute);
774 snd_opti93x_mute_reg(chip, OPTi93X_LINE_RIGHT_INPUT, mute);
775 snd_opti93x_mute_reg(chip, OPTi93X_MIC_LEFT_INPUT, mute);
776 snd_opti93x_mute_reg(chip, OPTi93X_MIC_RIGHT_INPUT, mute);
777 snd_opti93x_mute_reg(chip, OPTi93X_OUT_LEFT, mute);
778 snd_opti93x_mute_reg(chip, OPTi93X_OUT_RIGHT, mute);
779}
780
781
782static unsigned int snd_opti93x_get_count(unsigned char format,
783 unsigned int size)
784{
785 switch (format & 0xe0) {
786 case OPTi93X_LINEAR_16_LIT:
787 case OPTi93X_LINEAR_16_BIG:
788 size >>= 1;
789 break;
790 case OPTi93X_ADPCM_16:
791 return size >> 2;
792 }
793 return (format & OPTi93X_STEREO) ? (size >> 1) : size;
794}
795
796static unsigned int rates[] = { 5512, 6615, 8000, 9600, 11025, 16000,
797 18900, 22050, 27428, 32000, 33075, 37800,
798 44100, 48000 };
799#define RATES ARRAY_SIZE(rates)
800
801static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
802 .count = RATES,
803 .list = rates,
804 .mask = 0,
805};
806
807static unsigned char bits[] = { 0x01, 0x0f, 0x00, 0x0e, 0x03, 0x02,
808 0x05, 0x07, 0x04, 0x06, 0x0d, 0x09,
809 0x0b, 0x0c};
810
811static unsigned char snd_opti93x_get_freq(unsigned int rate)
812{
813 unsigned int i;
814
815 for (i = 0; i < RATES; i++) {
816 if (rate == rates[i])
817 return bits[i];
818 }
819 snd_BUG();
820 return bits[RATES-1];
821}
822
823static unsigned char snd_opti93x_get_format(opti93x_t *chip,
824 unsigned int format, int channels)
825{
826 unsigned char retval = OPTi93X_LINEAR_8;
827
828 switch (format) {
829 case SNDRV_PCM_FORMAT_MU_LAW:
830 retval = OPTi93X_ULAW_8;
831 break;
832 case SNDRV_PCM_FORMAT_A_LAW:
833 retval = OPTi93X_ALAW_8;
834 break;
835 case SNDRV_PCM_FORMAT_S16_LE:
836 retval = OPTi93X_LINEAR_16_LIT;
837 break;
838 case SNDRV_PCM_FORMAT_S16_BE:
839 retval = OPTi93X_LINEAR_16_BIG;
840 break;
841 case SNDRV_PCM_FORMAT_IMA_ADPCM:
842 retval = OPTi93X_ADPCM_16;
843 }
844 return (channels > 1) ? (retval | OPTi93X_STEREO) : retval;
845}
846
847
848static void snd_opti93x_playback_format(opti93x_t *chip, unsigned char fmt)
849{
850 unsigned char mask;
851
852 snd_opti93x_mute(chip, 1);
853
854 snd_opti93x_mce_up(chip);
855 mask = (chip->mode & OPTi93X_MODE_CAPTURE) ? 0xf0 : 0xff;
856 snd_opti93x_out_mask(chip, OPTi93X_PLAY_FORMAT, mask, fmt);
857 snd_opti93x_mce_down(chip);
858
859 snd_opti93x_mute(chip, 0);
860}
861
862static void snd_opti93x_capture_format(opti93x_t *chip, unsigned char fmt)
863{
864 snd_opti93x_mute(chip, 1);
865
866 snd_opti93x_mce_up(chip);
867 if (!(chip->mode & OPTi93X_MODE_PLAY))
868 snd_opti93x_out_mask(chip, OPTi93X_PLAY_FORMAT, 0x0f, fmt);
869 else
870 fmt = chip->image[OPTi93X_PLAY_FORMAT] & 0xf0;
871 snd_opti93x_out_image(chip, OPTi93X_CAPT_FORMAT, fmt);
872 snd_opti93x_mce_down(chip);
873
874 snd_opti93x_mute(chip, 0);
875}
876
877
878static int snd_opti93x_open(opti93x_t *chip, unsigned int mode)
879{
880 unsigned long flags;
881
882 spin_lock_irqsave(&chip->lock, flags);
883
884 if (chip->mode & mode) {
885 spin_unlock_irqrestore(&chip->lock, flags);
886 return -EAGAIN;
887 }
888
889 if (!(chip->mode & OPTi93X_MODE_OPEN)) {
890 outb(0x00, OPTi93X_PORT(chip, STATUS));
891 snd_opti93x_out_mask(chip, OPTi93X_PIN_CTRL,
892 OPTi93X_IRQ_ENABLE, OPTi93X_IRQ_ENABLE);
893 chip->mode = mode;
894 }
895 else
896 chip->mode |= mode;
897
898 spin_unlock_irqrestore(&chip->lock, flags);
899 return 0;
900}
901
902static void snd_opti93x_close(opti93x_t *chip, unsigned int mode)
903{
904 unsigned long flags;
905
906 spin_lock_irqsave(&chip->lock, flags);
907
908 chip->mode &= ~mode;
909 if (chip->mode & OPTi93X_MODE_OPEN) {
910 spin_unlock_irqrestore(&chip->lock, flags);
911 return;
912 }
913
914 snd_opti93x_mute(chip, 1);
915
916 outb(0, OPTi93X_PORT(chip, STATUS));
917 snd_opti93x_out_mask(chip, OPTi93X_PIN_CTRL, OPTi93X_IRQ_ENABLE,
918 ~OPTi93X_IRQ_ENABLE);
919
920 snd_opti93x_mce_up(chip);
921 snd_opti93x_out_image(chip, OPTi93X_IFACE_CONF, 0x00);
922 snd_opti93x_mce_down(chip);
923 chip->mode = 0;
924
925 snd_opti93x_mute(chip, 0);
926 spin_unlock_irqrestore(&chip->lock, flags);
927}
928
929static int snd_opti93x_trigger(snd_pcm_substream_t *substream,
930 unsigned char what, int cmd)
931{
932 opti93x_t *chip = snd_pcm_substream_chip(substream);
933
934 switch (cmd) {
935 case SNDRV_PCM_TRIGGER_START:
936 case SNDRV_PCM_TRIGGER_STOP:
937 {
938 unsigned int what = 0;
939 struct list_head *pos;
940 snd_pcm_substream_t *s;
941 snd_pcm_group_for_each(pos, substream) {
942 s = snd_pcm_group_substream_entry(pos);
943 if (s == chip->playback_substream) {
944 what |= OPTi93X_PLAYBACK_ENABLE;
945 snd_pcm_trigger_done(s, substream);
946 } else if (s == chip->capture_substream) {
947 what |= OPTi93X_CAPTURE_ENABLE;
948 snd_pcm_trigger_done(s, substream);
949 }
950 }
951 spin_lock(&chip->lock);
952 if (cmd == SNDRV_PCM_TRIGGER_START) {
953 snd_opti93x_out_mask(chip, OPTi93X_IFACE_CONF, what, what);
954 if (what & OPTi93X_CAPTURE_ENABLE)
955 udelay(50);
956 } else
957 snd_opti93x_out_mask(chip, OPTi93X_IFACE_CONF, what, 0x00);
958 spin_unlock(&chip->lock);
959 break;
960 }
961 default:
962 return -EINVAL;
963 }
964 return 0;
965}
966
967static int snd_opti93x_playback_trigger(snd_pcm_substream_t *substream, int cmd)
968{
969 return snd_opti93x_trigger(substream,
970 OPTi93X_PLAYBACK_ENABLE, cmd);
971}
972
973static int snd_opti93x_capture_trigger(snd_pcm_substream_t * substream, int cmd)
974{
975 return snd_opti93x_trigger(substream,
976 OPTi93X_CAPTURE_ENABLE, cmd);
977}
978
979static int snd_opti93x_hw_params(snd_pcm_substream_t * substream,
980 snd_pcm_hw_params_t * hw_params)
981{
982 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
983}
984
985
986static int snd_opti93x_hw_free(snd_pcm_substream_t * substream)
987{
988 snd_pcm_lib_free_pages(substream);
989 return 0;
990}
991
992
993static int snd_opti93x_playback_prepare(snd_pcm_substream_t * substream)
994{
995 opti93x_t *chip = snd_pcm_substream_chip(substream);
996 snd_pcm_runtime_t *runtime = substream->runtime;
997 unsigned long flags;
998 unsigned char format;
999 unsigned int count = snd_pcm_lib_period_bytes(substream);
1000 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
1001
1002 spin_lock_irqsave(&chip->lock, flags);
1003
1004 chip->p_dma_size = size;
1005 snd_opti93x_out_mask(chip, OPTi93X_IFACE_CONF,
1006 OPTi93X_PLAYBACK_ENABLE | OPTi93X_PLAYBACK_PIO,
1007 ~(OPTi93X_PLAYBACK_ENABLE | OPTi93X_PLAYBACK_PIO));
1008
1009 snd_dma_program(chip->dma1, runtime->dma_addr, size,
1010 DMA_MODE_WRITE | DMA_AUTOINIT);
1011
1012 format = snd_opti93x_get_freq(runtime->rate);
1013 format |= snd_opti93x_get_format(chip, runtime->format,
1014 runtime->channels);
1015 snd_opti93x_playback_format(chip, format);
1016 format = chip->image[OPTi93X_PLAY_FORMAT];
1017
1018 count = snd_opti93x_get_count(format, count) - 1;
1019 snd_opti93x_out_image(chip, OPTi93X_PLAY_LWR_CNT, count);
1020 snd_opti93x_out_image(chip, OPTi93X_PLAY_UPR_CNT, count >> 8);
1021
1022 spin_unlock_irqrestore(&chip->lock, flags);
1023 return 0;
1024}
1025
1026static int snd_opti93x_capture_prepare(snd_pcm_substream_t *substream)
1027{
1028 opti93x_t *chip = snd_pcm_substream_chip(substream);
1029 snd_pcm_runtime_t *runtime = substream->runtime;
1030 unsigned long flags;
1031 unsigned char format;
1032 unsigned int count = snd_pcm_lib_period_bytes(substream);
1033 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
1034
1035 spin_lock_irqsave(&chip->lock, flags);
1036
1037 chip->c_dma_size = size;
1038 snd_opti93x_out_mask(chip, OPTi93X_IFACE_CONF,
Clemens Ladischdb673192005-09-05 10:36:27 +02001039 OPTi93X_CAPTURE_ENABLE | OPTi93X_CAPTURE_PIO, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001040
1041 snd_dma_program(chip->dma2, runtime->dma_addr, size,
1042 DMA_MODE_READ | DMA_AUTOINIT);
1043
1044 format = snd_opti93x_get_freq(runtime->rate);
1045 format |= snd_opti93x_get_format(chip, runtime->format,
1046 runtime->channels);
1047 snd_opti93x_capture_format(chip, format);
1048 format = chip->image[OPTi93X_CAPT_FORMAT];
1049
1050 count = snd_opti93x_get_count(format, count) - 1;
1051 snd_opti93x_out_image(chip, OPTi93X_CAPT_LWR_CNT, count);
1052 snd_opti93x_out_image(chip, OPTi93X_CAPT_UPR_CNT, count >> 8);
1053
1054 spin_unlock_irqrestore(&chip->lock, flags);
1055 return 0;
1056}
1057
1058static snd_pcm_uframes_t snd_opti93x_playback_pointer(snd_pcm_substream_t *substream)
1059{
1060 opti93x_t *chip = snd_pcm_substream_chip(substream);
1061 size_t ptr;
1062
1063 if (!(chip->image[OPTi93X_IFACE_CONF] & OPTi93X_PLAYBACK_ENABLE))
1064 return 0;
1065
1066 ptr = snd_dma_pointer(chip->dma1, chip->p_dma_size);
1067 return bytes_to_frames(substream->runtime, ptr);
1068}
1069
1070static snd_pcm_uframes_t snd_opti93x_capture_pointer(snd_pcm_substream_t *substream)
1071{
1072 opti93x_t *chip = snd_pcm_substream_chip(substream);
1073 size_t ptr;
1074
1075 if (!(chip->image[OPTi93X_IFACE_CONF] & OPTi93X_CAPTURE_ENABLE))
1076 return 0;
1077
1078 ptr = snd_dma_pointer(chip->dma2, chip->c_dma_size);
1079 return bytes_to_frames(substream->runtime, ptr);
1080}
1081
1082
1083static void snd_opti93x_overrange(opti93x_t *chip)
1084{
1085 unsigned long flags;
1086
1087 spin_lock_irqsave(&chip->lock, flags);
1088
1089 if (snd_opti93x_in(chip, OPTi93X_ERR_INIT) & (0x08 | 0x02))
1090 chip->capture_substream->runtime->overrange++;
1091
1092 spin_unlock_irqrestore(&chip->lock, flags);
1093}
1094
1095static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1096{
1097 opti93x_t *codec = dev_id;
1098 unsigned char status;
1099
1100 status = snd_opti9xx_read(codec->chip, OPTi9XX_MC_REG(11));
1101 if ((status & OPTi93X_IRQ_PLAYBACK) && codec->playback_substream)
1102 snd_pcm_period_elapsed(codec->playback_substream);
1103 if ((status & OPTi93X_IRQ_CAPTURE) && codec->capture_substream) {
1104 snd_opti93x_overrange(codec);
1105 snd_pcm_period_elapsed(codec->capture_substream);
1106 }
1107 outb(0x00, OPTi93X_PORT(codec, STATUS));
1108 return IRQ_HANDLED;
1109}
1110
1111
1112static snd_pcm_hardware_t snd_opti93x_playback = {
1113 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1114 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START),
1115 .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM |
1116 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE),
1117 .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
1118 .rate_min = 5512,
1119 .rate_max = 48000,
1120 .channels_min = 1,
1121 .channels_max = 2,
1122 .buffer_bytes_max = (128*1024),
1123 .period_bytes_min = 64,
1124 .period_bytes_max = (128*1024),
1125 .periods_min = 1,
1126 .periods_max = 1024,
1127 .fifo_size = 0,
1128};
1129
1130static snd_pcm_hardware_t snd_opti93x_capture = {
1131 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1132 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START),
1133 .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM |
1134 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE),
1135 .rates = SNDRV_PCM_RATE_8000_48000,
1136 .rate_min = 5512,
1137 .rate_max = 48000,
1138 .channels_min = 1,
1139 .channels_max = 2,
1140 .buffer_bytes_max = (128*1024),
1141 .period_bytes_min = 64,
1142 .period_bytes_max = (128*1024),
1143 .periods_min = 1,
1144 .periods_max = 1024,
1145 .fifo_size = 0,
1146};
1147
1148static int snd_opti93x_playback_open(snd_pcm_substream_t *substream)
1149{
1150 int error;
1151 opti93x_t *chip = snd_pcm_substream_chip(substream);
1152 snd_pcm_runtime_t *runtime = substream->runtime;
1153
1154 if ((error = snd_opti93x_open(chip, OPTi93X_MODE_PLAY)) < 0)
1155 return error;
1156 snd_pcm_set_sync(substream);
1157 chip->playback_substream = substream;
1158 runtime->hw = snd_opti93x_playback;
1159 snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.buffer_bytes_max);
1160 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
1161 return error;
1162}
1163
1164static int snd_opti93x_capture_open(snd_pcm_substream_t *substream)
1165{
1166 int error;
1167 opti93x_t *chip = snd_pcm_substream_chip(substream);
1168 snd_pcm_runtime_t *runtime = substream->runtime;
1169
1170 if ((error = snd_opti93x_open(chip, OPTi93X_MODE_CAPTURE)) < 0)
1171 return error;
1172 runtime->hw = snd_opti93x_capture;
1173 snd_pcm_set_sync(substream);
1174 chip->capture_substream = substream;
1175 snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.buffer_bytes_max);
1176 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
1177 return error;
1178}
1179
1180static int snd_opti93x_playback_close(snd_pcm_substream_t *substream)
1181{
1182 opti93x_t *chip = snd_pcm_substream_chip(substream);
1183
1184 chip->playback_substream = NULL;
1185 snd_opti93x_close(chip, OPTi93X_MODE_PLAY);
1186 return 0;
1187}
1188
1189static int snd_opti93x_capture_close(snd_pcm_substream_t *substream)
1190{
1191 opti93x_t *chip = snd_pcm_substream_chip(substream);
1192
1193 chip->capture_substream = NULL;
1194 snd_opti93x_close(chip, OPTi93X_MODE_CAPTURE);
1195 return 0;
1196}
1197
1198
1199static void snd_opti93x_init(opti93x_t *chip)
1200{
1201 unsigned long flags;
1202 int i;
1203
1204 spin_lock_irqsave(&chip->lock, flags);
1205 snd_opti93x_mce_up(chip);
1206
1207 for (i = 0; i < 32; i++)
1208 snd_opti93x_out_image(chip, i, snd_opti93x_default_image[i]);
1209
1210 snd_opti93x_mce_down(chip);
1211 spin_unlock_irqrestore(&chip->lock, flags);
1212}
1213
1214static int snd_opti93x_probe(opti93x_t *chip)
1215{
1216 unsigned long flags;
1217 unsigned char val;
1218
1219 spin_lock_irqsave(&chip->lock, flags);
1220 val = snd_opti93x_in(chip, OPTi93X_ID) & 0x0f;
1221 spin_unlock_irqrestore(&chip->lock, flags);
1222
1223 return (val == 0x0a) ? 0 : -ENODEV;
1224}
1225
1226static int snd_opti93x_free(opti93x_t *chip)
1227{
Takashi Iwaib1d57762005-10-10 11:56:31 +02001228 release_and_free_resource(chip->res_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001229 if (chip->dma1 >= 0) {
1230 disable_dma(chip->dma1);
1231 free_dma(chip->dma1);
1232 }
1233 if (chip->dma2 >= 0) {
1234 disable_dma(chip->dma2);
1235 free_dma(chip->dma2);
1236 }
1237 if (chip->irq >= 0) {
1238 free_irq(chip->irq, chip);
1239 }
1240 kfree(chip);
1241 return 0;
1242}
1243
1244static int snd_opti93x_dev_free(snd_device_t *device)
1245{
1246 opti93x_t *chip = device->device_data;
1247 return snd_opti93x_free(chip);
1248}
1249
1250static const char *snd_opti93x_chip_id(opti93x_t *codec)
1251{
1252 switch (codec->hardware) {
1253 case OPTi9XX_HW_82C930: return "82C930";
1254 case OPTi9XX_HW_82C931: return "82C931";
1255 case OPTi9XX_HW_82C933: return "82C933";
1256 default: return "???";
1257 }
1258}
1259
1260static int snd_opti93x_create(snd_card_t *card, opti9xx_t *chip,
1261 int dma1, int dma2,
1262 opti93x_t **rcodec)
1263{
1264 static snd_device_ops_t ops = {
1265 .dev_free = snd_opti93x_dev_free,
1266 };
1267 int error;
1268 opti93x_t *codec;
1269
1270 *rcodec = NULL;
Takashi Iwai9e76a762005-09-09 14:21:17 +02001271 codec = kzalloc(sizeof(*codec), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001272 if (codec == NULL)
1273 return -ENOMEM;
1274 codec->irq = -1;
1275 codec->dma1 = -1;
1276 codec->dma2 = -1;
1277
1278 if ((codec->res_port = request_region(chip->wss_base + 4, 4, "OPTI93x CODEC")) == NULL) {
1279 snd_printk(KERN_ERR "opti9xx: can't grab port 0x%lx\n", chip->wss_base + 4);
1280 snd_opti93x_free(codec);
1281 return -EBUSY;
1282 }
1283 if (request_dma(dma1, "OPTI93x - 1")) {
1284 snd_printk(KERN_ERR "opti9xx: can't grab DMA1 %d\n", dma1);
1285 snd_opti93x_free(codec);
1286 return -EBUSY;
1287 }
1288 codec->dma1 = chip->dma1;
1289 if (request_dma(dma2, "OPTI93x - 2")) {
1290 snd_printk(KERN_ERR "opti9xx: can't grab DMA2 %d\n", dma2);
1291 snd_opti93x_free(codec);
1292 return -EBUSY;
1293 }
1294 codec->dma2 = chip->dma2;
1295
1296 if (request_irq(chip->irq, snd_opti93x_interrupt, SA_INTERRUPT, DRIVER_NAME" - WSS", codec)) {
1297 snd_printk(KERN_ERR "opti9xx: can't grab IRQ %d\n", chip->irq);
1298 snd_opti93x_free(codec);
1299 return -EBUSY;
1300 }
1301
1302 codec->card = card;
1303 codec->port = chip->wss_base + 4;
1304 codec->irq = chip->irq;
1305
1306 spin_lock_init(&codec->lock);
1307 codec->hardware = chip->hardware;
1308 codec->chip = chip;
1309
1310 if ((error = snd_opti93x_probe(codec))) {
1311 snd_opti93x_free(codec);
1312 return error;
1313 }
1314
1315 snd_opti93x_init(codec);
1316
1317 /* Register device */
1318 if ((error = snd_device_new(card, SNDRV_DEV_LOWLEVEL, codec, &ops)) < 0) {
1319 snd_opti93x_free(codec);
1320 return error;
1321 }
1322
1323 *rcodec = codec;
1324 return 0;
1325}
1326
1327static snd_pcm_ops_t snd_opti93x_playback_ops = {
1328 .open = snd_opti93x_playback_open,
1329 .close = snd_opti93x_playback_close,
1330 .ioctl = snd_pcm_lib_ioctl,
1331 .hw_params = snd_opti93x_hw_params,
1332 .hw_free = snd_opti93x_hw_free,
1333 .prepare = snd_opti93x_playback_prepare,
1334 .trigger = snd_opti93x_playback_trigger,
1335 .pointer = snd_opti93x_playback_pointer,
1336};
1337
1338static snd_pcm_ops_t snd_opti93x_capture_ops = {
1339 .open = snd_opti93x_capture_open,
1340 .close = snd_opti93x_capture_close,
1341 .ioctl = snd_pcm_lib_ioctl,
1342 .hw_params = snd_opti93x_hw_params,
1343 .hw_free = snd_opti93x_hw_free,
1344 .prepare = snd_opti93x_capture_prepare,
1345 .trigger = snd_opti93x_capture_trigger,
1346 .pointer = snd_opti93x_capture_pointer,
1347};
1348
1349static void snd_opti93x_pcm_free(snd_pcm_t *pcm)
1350{
1351 opti93x_t *codec = pcm->private_data;
1352 codec->pcm = NULL;
1353 snd_pcm_lib_preallocate_free_for_all(pcm);
1354}
1355
1356static int snd_opti93x_pcm(opti93x_t *codec, int device, snd_pcm_t **rpcm)
1357{
1358 int error;
1359 snd_pcm_t *pcm;
1360
1361 if ((error = snd_pcm_new(codec->card, "OPTi 82C93X", device, 1, 1, &pcm)))
1362 return error;
1363
1364 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_opti93x_playback_ops);
1365 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_opti93x_capture_ops);
1366
1367 pcm->private_data = codec;
1368 pcm->private_free = snd_opti93x_pcm_free;
1369 pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
1370
1371 strcpy(pcm->name, snd_opti93x_chip_id(codec));
1372
1373 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1374 snd_dma_isa_data(),
1375 64*1024, codec->dma1 > 3 || codec->dma2 > 3 ? 128*1024 : 64*1024);
1376
1377 codec->pcm = pcm;
1378 if (rpcm)
1379 *rpcm = pcm;
1380 return 0;
1381}
1382
1383/*
1384 * MIXER part
1385 */
1386
1387static int snd_opti93x_info_mux(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1388{
1389 static char *texts[4] = {
1390 "Line1", "Aux", "Mic", "Mix"
1391 };
1392
1393 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1394 uinfo->count = 2;
1395 uinfo->value.enumerated.items = 4;
1396 if (uinfo->value.enumerated.item > 3)
1397 uinfo->value.enumerated.item = 3;
1398 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1399 return 0;
1400}
1401
1402static int snd_opti93x_get_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1403{
1404 opti93x_t *chip = snd_kcontrol_chip(kcontrol);
1405 unsigned long flags;
1406
1407 spin_lock_irqsave(&chip->lock, flags);
1408 ucontrol->value.enumerated.item[0] = (chip->image[OPTi93X_MIXOUT_LEFT] & OPTi93X_MIXOUT_MIXER) >> 6;
1409 ucontrol->value.enumerated.item[1] = (chip->image[OPTi93X_MIXOUT_RIGHT] & OPTi93X_MIXOUT_MIXER) >> 6;
1410 spin_unlock_irqrestore(&chip->lock, flags);
1411 return 0;
1412}
1413
1414static int snd_opti93x_put_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1415{
1416 opti93x_t *chip = snd_kcontrol_chip(kcontrol);
1417 unsigned long flags;
1418 unsigned short left, right;
1419 int change;
1420
1421 if (ucontrol->value.enumerated.item[0] > 3 ||
1422 ucontrol->value.enumerated.item[1] > 3)
1423 return -EINVAL;
1424 left = ucontrol->value.enumerated.item[0] << 6;
1425 right = ucontrol->value.enumerated.item[1] << 6;
1426 spin_lock_irqsave(&chip->lock, flags);
1427 left = (chip->image[OPTi93X_MIXOUT_LEFT] & ~OPTi93X_MIXOUT_MIXER) | left;
1428 right = (chip->image[OPTi93X_MIXOUT_RIGHT] & ~OPTi93X_MIXOUT_MIXER) | right;
1429 change = left != chip->image[OPTi93X_MIXOUT_LEFT] ||
1430 right != chip->image[OPTi93X_MIXOUT_RIGHT];
1431 snd_opti93x_out_image(chip, OPTi93X_MIXOUT_LEFT, left);
1432 snd_opti93x_out_image(chip, OPTi93X_MIXOUT_RIGHT, right);
1433 spin_unlock_irqrestore(&chip->lock, flags);
1434 return change;
1435}
1436
1437#if 0
1438
1439#define OPTi93X_SINGLE(xname, xindex, reg, shift, mask, invert) \
1440{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
1441 .info = snd_opti93x_info_single, \
1442 .get = snd_opti93x_get_single, .put = snd_opti93x_put_single, \
1443 .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
1444
1445static int snd_opti93x_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1446{
1447 int mask = (kcontrol->private_value >> 16) & 0xff;
1448
1449 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
1450 uinfo->count = 1;
1451 uinfo->value.integer.min = 0;
1452 uinfo->value.integer.max = mask;
1453 return 0;
1454}
1455
1456static int snd_opti93x_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1457{
1458 opti93x_t *chip = snd_kcontrol_chip(kcontrol);
1459 unsigned long flags;
1460 int reg = kcontrol->private_value & 0xff;
1461 int shift = (kcontrol->private_value >> 8) & 0xff;
1462 int mask = (kcontrol->private_value >> 16) & 0xff;
1463 int invert = (kcontrol->private_value >> 24) & 0xff;
1464
1465 spin_lock_irqsave(&chip->lock, flags);
1466 ucontrol->value.integer.value[0] = (chip->image[reg] >> shift) & mask;
1467 spin_unlock_irqrestore(&chip->lock, flags);
1468 if (invert)
1469 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
1470 return 0;
1471}
1472
1473static int snd_opti93x_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1474{
1475 opti93x_t *chip = snd_kcontrol_chip(kcontrol);
1476 unsigned long flags;
1477 int reg = kcontrol->private_value & 0xff;
1478 int shift = (kcontrol->private_value >> 8) & 0xff;
1479 int mask = (kcontrol->private_value >> 16) & 0xff;
1480 int invert = (kcontrol->private_value >> 24) & 0xff;
1481 int change;
1482 unsigned short val;
1483
1484 val = (ucontrol->value.integer.value[0] & mask);
1485 if (invert)
1486 val = mask - val;
1487 val <<= shift;
1488 spin_lock_irqsave(&chip->lock, flags);
1489 val = (chip->image[reg] & ~(mask << shift)) | val;
1490 change = val != chip->image[reg];
1491 snd_opti93x_out(chip, reg, val);
1492 spin_unlock_irqrestore(&chip->lock, flags);
1493 return change;
1494}
1495
1496#endif /* single */
1497
1498#define OPTi93X_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
1499{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
1500 .info = snd_opti93x_info_double, \
1501 .get = snd_opti93x_get_double, .put = snd_opti93x_put_double, \
1502 .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
1503
1504#define OPTi93X_DOUBLE_INVERT_INVERT(xctl) \
1505 do { xctl.private_value ^= 22; } while (0)
1506#define OPTi93X_DOUBLE_CHANGE_REGS(xctl, left_reg, right_reg) \
1507 do { xctl.private_value &= ~0x0000ffff; \
1508 xctl.private_value |= left_reg | (right_reg << 8); } while (0)
1509
1510static int snd_opti93x_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1511{
1512 int mask = (kcontrol->private_value >> 24) & 0xff;
1513
1514 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
1515 uinfo->count = 2;
1516 uinfo->value.integer.min = 0;
1517 uinfo->value.integer.max = mask;
1518 return 0;
1519}
1520
1521static int snd_opti93x_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1522{
1523 opti93x_t *chip = snd_kcontrol_chip(kcontrol);
1524 unsigned long flags;
1525 int left_reg = kcontrol->private_value & 0xff;
1526 int right_reg = (kcontrol->private_value >> 8) & 0xff;
1527 int shift_left = (kcontrol->private_value >> 16) & 0x07;
1528 int shift_right = (kcontrol->private_value >> 19) & 0x07;
1529 int mask = (kcontrol->private_value >> 24) & 0xff;
1530 int invert = (kcontrol->private_value >> 22) & 1;
1531
1532 spin_lock_irqsave(&chip->lock, flags);
1533 ucontrol->value.integer.value[0] = (chip->image[left_reg] >> shift_left) & mask;
1534 ucontrol->value.integer.value[1] = (chip->image[right_reg] >> shift_right) & mask;
1535 spin_unlock_irqrestore(&chip->lock, flags);
1536 if (invert) {
1537 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
1538 ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
1539 }
1540 return 0;
1541}
1542
1543static int snd_opti93x_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1544{
1545 opti93x_t *chip = snd_kcontrol_chip(kcontrol);
1546 unsigned long flags;
1547 int left_reg = kcontrol->private_value & 0xff;
1548 int right_reg = (kcontrol->private_value >> 8) & 0xff;
1549 int shift_left = (kcontrol->private_value >> 16) & 0x07;
1550 int shift_right = (kcontrol->private_value >> 19) & 0x07;
1551 int mask = (kcontrol->private_value >> 24) & 0xff;
1552 int invert = (kcontrol->private_value >> 22) & 1;
1553 int change;
1554 unsigned short val1, val2;
1555
1556 val1 = ucontrol->value.integer.value[0] & mask;
1557 val2 = ucontrol->value.integer.value[1] & mask;
1558 if (invert) {
1559 val1 = mask - val1;
1560 val2 = mask - val2;
1561 }
1562 val1 <<= shift_left;
1563 val2 <<= shift_right;
1564 spin_lock_irqsave(&chip->lock, flags);
1565 val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1;
1566 val2 = (chip->image[right_reg] & ~(mask << shift_right)) | val2;
1567 change = val1 != chip->image[left_reg] || val2 != chip->image[right_reg];
1568 snd_opti93x_out_image(chip, left_reg, val1);
1569 snd_opti93x_out_image(chip, right_reg, val2);
1570 spin_unlock_irqrestore(&chip->lock, flags);
1571 return change;
1572}
1573
1574static snd_kcontrol_new_t snd_opti93x_controls[] = {
1575OPTi93X_DOUBLE("Master Playback Switch", 0, OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1),
1576OPTi93X_DOUBLE("Master Playback Volume", 0, OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1),
1577OPTi93X_DOUBLE("PCM Playback Switch", 0, OPTi93X_DAC_LEFT, OPTi93X_DAC_RIGHT, 7, 7, 1, 1),
1578OPTi93X_DOUBLE("PCM Playback Volume", 0, OPTi93X_DAC_LEFT, OPTi93X_DAC_RIGHT, 0, 0, 31, 1),
1579OPTi93X_DOUBLE("FM Playback Switch", 0, OPTi931_FM_LEFT_INPUT, OPTi931_FM_RIGHT_INPUT, 7, 7, 1, 1),
1580OPTi93X_DOUBLE("FM Playback Volume", 0, OPTi931_FM_LEFT_INPUT, OPTi931_FM_RIGHT_INPUT, 1, 1, 15, 1),
1581OPTi93X_DOUBLE("Line Playback Switch", 0, OPTi93X_LINE_LEFT_INPUT, OPTi93X_LINE_RIGHT_INPUT, 7, 7, 1, 1),
1582OPTi93X_DOUBLE("Line Playback Volume", 0, OPTi93X_LINE_LEFT_INPUT, OPTi93X_LINE_RIGHT_INPUT, 1, 1, 15, 1),
1583OPTi93X_DOUBLE("Mic Playback Switch", 0, OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 7, 7, 1, 1),
1584OPTi93X_DOUBLE("Mic Playback Volume", 0, OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 1, 1, 15, 1),
1585OPTi93X_DOUBLE("Mic Boost", 0, OPTi93X_MIXOUT_LEFT, OPTi93X_MIXOUT_RIGHT, 5, 5, 1, 1),
1586OPTi93X_DOUBLE("CD Playback Switch", 0, OPTi93X_CD_LEFT_INPUT, OPTi93X_CD_RIGHT_INPUT, 7, 7, 1, 1),
1587OPTi93X_DOUBLE("CD Playback Volume", 0, OPTi93X_CD_LEFT_INPUT, OPTi93X_CD_RIGHT_INPUT, 1, 1, 15, 1),
1588OPTi93X_DOUBLE("Aux Playback Switch", 0, OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 7, 7, 1, 1),
1589OPTi93X_DOUBLE("Aux Playback Volume", 0, OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 1, 1, 15, 1),
1590OPTi93X_DOUBLE("Capture Volume", 0, OPTi93X_MIXOUT_LEFT, OPTi93X_MIXOUT_RIGHT, 0, 0, 15, 0),
1591{
1592 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1593 .name = "Capture Source",
1594 .info = snd_opti93x_info_mux,
1595 .get = snd_opti93x_get_mux,
1596 .put = snd_opti93x_put_mux,
1597}
1598};
1599
1600static int snd_opti93x_mixer(opti93x_t *chip)
1601{
1602 snd_card_t *card;
1603 snd_kcontrol_new_t knew;
1604 int err;
1605 unsigned int idx;
1606
1607 snd_assert(chip != NULL && chip->card != NULL, return -EINVAL);
1608
1609 card = chip->card;
1610
1611 strcpy(card->mixername, snd_opti93x_chip_id(chip));
1612
1613 for (idx = 0; idx < ARRAY_SIZE(snd_opti93x_controls); idx++) {
1614 knew = snd_opti93x_controls[idx];
1615 if (chip->hardware == OPTi9XX_HW_82C930) {
1616 if (strstr(knew.name, "FM")) /* skip FM controls */
1617 continue;
1618 else if (strcmp(knew.name, "Mic Playback Volume"))
1619 OPTi93X_DOUBLE_INVERT_INVERT(knew);
1620 else if (strstr(knew.name, "Aux"))
1621 OPTi93X_DOUBLE_CHANGE_REGS(knew, OPTi930_AUX_LEFT_INPUT, OPTi930_AUX_RIGHT_INPUT);
1622 else if (strcmp(knew.name, "PCM Playback Volume"))
1623 OPTi93X_DOUBLE_INVERT_INVERT(knew);
1624 else if (strcmp(knew.name, "Master Playback Volume"))
1625 OPTi93X_DOUBLE_INVERT_INVERT(knew);
1626 }
1627 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_opti93x_controls[idx], chip))) < 0)
1628 return err;
1629 }
1630 return 0;
1631}
1632
1633#endif /* OPTi93X */
1634
1635static int __devinit snd_card_opti9xx_detect(snd_card_t *card, opti9xx_t *chip)
1636{
1637 int i, err;
1638
1639#ifndef OPTi93X
1640 for (i = OPTi9XX_HW_82C928; i < OPTi9XX_HW_82C930; i++) {
1641 unsigned char value;
1642
1643 if ((err = snd_opti9xx_init(chip, i)) < 0)
1644 return err;
1645
1646 if ((chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size, "OPTi9xx MC")) == NULL)
1647 continue;
1648
1649 value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(1));
1650 if ((value != 0xff) && (value != inb(chip->mc_base + 1)))
1651 if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1)))
1652 return 1;
1653
Takashi Iwaib1d57762005-10-10 11:56:31 +02001654 release_and_free_resource(chip->res_mc_base);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001655 chip->res_mc_base = NULL;
1656
1657 }
1658#else /* OPTi93X */
1659 for (i = OPTi9XX_HW_82C931; i >= OPTi9XX_HW_82C930; i--) {
1660 unsigned long flags;
1661 unsigned char value;
1662
1663 if ((err = snd_opti9xx_init(chip, i)) < 0)
1664 return err;
1665
1666 if ((chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size, "OPTi9xx MC")) == NULL)
1667 continue;
1668
1669 spin_lock_irqsave(&chip->lock, flags);
1670 outb(chip->password, chip->mc_base + chip->pwd_reg);
1671 outb(((chip->mc_indir_index & (1 << 8)) >> 4) |
1672 ((chip->mc_indir_index & 0xf0) >> 4), chip->mc_base);
1673 spin_unlock_irqrestore(&chip->lock, flags);
1674
1675 value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(7));
1676 snd_opti9xx_write(chip, OPTi9XX_MC_REG(7), 0xff - value);
1677 if (snd_opti9xx_read(chip, OPTi9XX_MC_REG(7)) == 0xff - value)
1678 return 1;
1679
Takashi Iwaib1d57762005-10-10 11:56:31 +02001680 release_and_free_resource(chip->res_mc_base);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001681 chip->res_mc_base = NULL;
1682 }
1683#endif /* OPTi93X */
1684
1685 return -ENODEV;
1686}
1687
1688#ifdef CONFIG_PNP
1689static int __devinit snd_card_opti9xx_pnp(opti9xx_t *chip, struct pnp_card_link *card,
1690 const struct pnp_card_device_id *pid)
1691{
1692 struct pnp_dev *pdev;
1693 struct pnp_resource_table *cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
1694 int err;
1695
1696 chip->dev = pnp_request_card_device(card, pid->devs[0].id, NULL);
1697 if (chip->dev == NULL) {
1698 kfree(cfg);
1699 return -EBUSY;
1700 }
1701 chip->devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL);
1702
1703 pdev = chip->dev;
1704 pnp_init_resource_table(cfg);
1705
1706#ifdef OPTi93X
1707 if (port != SNDRV_AUTO_PORT)
1708 pnp_resource_change(&cfg->port_resource[0], port + 4, 4);
1709#else
1710 if (pid->driver_data != 0x0924 && port != SNDRV_AUTO_PORT)
1711 pnp_resource_change(&cfg->port_resource[1], port, 4);
1712#endif /* OPTi93X */
1713 if (irq != SNDRV_AUTO_IRQ)
1714 pnp_resource_change(&cfg->irq_resource[0], irq, 1);
1715 if (dma1 != SNDRV_AUTO_DMA)
1716 pnp_resource_change(&cfg->dma_resource[0], dma1, 1);
1717#if defined(CS4231) || defined(OPTi93X)
1718 if (dma2 != SNDRV_AUTO_DMA)
1719 pnp_resource_change(&cfg->dma_resource[1], dma2, 1);
1720#else
1721#ifdef snd_opti9xx_fixup_dma2
1722 snd_opti9xx_fixup_dma2(pdev);
1723#endif
1724#endif /* CS4231 || OPTi93X */
1725#ifdef OPTi93X
1726 if (fm_port > 0 && fm_port != SNDRV_AUTO_PORT)
1727 pnp_resource_change(&cfg->port_resource[1], fm_port, 4);
1728#else
1729 if (fm_port > 0 && fm_port != SNDRV_AUTO_PORT)
1730 pnp_resource_change(&cfg->port_resource[2], fm_port, 4);
1731#endif
1732 if (pnp_manual_config_dev(pdev, cfg, 0) < 0)
1733 snd_printk(KERN_ERR "AUDIO the requested resources are invalid, using auto config\n");
1734 err = pnp_activate_dev(pdev);
1735 if (err < 0) {
1736 snd_printk(KERN_ERR "AUDIO pnp configure failure: %d\n", err);
1737 kfree(cfg);
1738 return err;
1739 }
1740
1741#ifdef OPTi93X
1742 port = pnp_port_start(pdev, 0) - 4;
1743 fm_port = pnp_port_start(pdev, 1);
1744#else
1745 if (pid->driver_data != 0x0924)
1746 port = pnp_port_start(pdev, 1);
1747 fm_port = pnp_port_start(pdev, 2);
1748#endif /* OPTi93X */
1749 irq = pnp_irq(pdev, 0);
1750 dma1 = pnp_dma(pdev, 0);
1751#if defined(CS4231) || defined(OPTi93X)
1752 dma2 = pnp_dma(pdev, 1);
1753#endif /* CS4231 || OPTi93X */
1754
1755 pdev = chip->devmpu;
1756 if (pdev && mpu_port > 0) {
1757 pnp_init_resource_table(cfg);
1758
1759 if (mpu_port != SNDRV_AUTO_PORT)
1760 pnp_resource_change(&cfg->port_resource[0], mpu_port, 2);
1761 if (mpu_irq != SNDRV_AUTO_IRQ)
1762 pnp_resource_change(&cfg->irq_resource[0], mpu_irq, 1);
1763
1764 if (pnp_manual_config_dev(pdev, cfg, 0) < 0)
1765 snd_printk(KERN_ERR "AUDIO the requested resources are invalid, using auto config\n");
1766 err = pnp_activate_dev(pdev);
1767 if (err < 0) {
1768 snd_printk(KERN_ERR "AUDIO pnp configure failure\n");
1769 mpu_port = -1;
1770 chip->devmpu = NULL;
1771 } else {
1772 mpu_port = pnp_port_start(pdev, 0);
1773 mpu_irq = pnp_irq(pdev, 0);
1774 }
1775 }
1776 kfree(cfg);
1777 return pid->driver_data;
1778}
1779#endif /* CONFIG_PNP */
1780
1781#if 0
1782static int __devinit snd_card_opti9xx_resources(struct snd_card_opti9xx *chip,
1783 snd_card_t *card)
1784{
1785 int error, i, pnp = 0;
1786
1787#ifdef CONFIG_PNP
1788 pnp = chip->dev != NULL;
1789#endif /* CONFIG_PNP */
1790
1791#ifndef OPTi93X
1792 if (chip->chip->hardware == OPTi9XX_HW_82C928)
1793 mpu_port = -1;
1794#endif /* OPTi93X */
1795 error = 0;
1796 if (!pnp && (mpu_port == SNDRV_DEFAULT_PORT1)) {
1797 for (i = 0; possible_mpu_ports[i] != -1; i++)
1798 if (!snd_register_ioport(card, possible_mpu_ports[i], 2,
1799 DRIVER_NAME" - MPU-401", NULL)) {
1800 mpu_port = possible_mpu_ports[i];
1801 break;
1802 }
1803 if (mpu_port == SNDRV_DEFAULT_PORT1)
1804 error = -EBUSY;
1805 }
1806 else
1807 error = (mpu_port == -1) ? -ENODEV :
1808 snd_register_ioport(card, mpu_port, 2,
1809 DRIVER_NAME" - MPU-401", NULL);
1810 if (error)
1811 chip->chip->mpu_port = -1;
1812 else if (pnp && (irq == mpu_irq))
1813 chip->chip->mpu_irq = mpu_irq;
1814 else if (!snd_register_interrupt(card,
1815 DRIVER_NAME" - MPU-401",
1816 mpu_irq, SNDRV_IRQ_TYPE_ISA,
1817 snd_card_opti9xx_mpu_interrupt, chip,
1818 pnp ? no_alternatives : possible_mpu_irqs,
1819 &chip->mpuirqptr)) {
1820 chip->chip->mpu_port = mpu_port;
1821 chip->chip->mpu_irq = chip->mpuirqptr->irq;
1822 }
1823 else
1824 chip->chip->mpu_port = -1;
1825
1826 if (!pnp && (port == SNDRV_DEFAULT_PORT1)) {
1827 for (i = 0; possible_ports[i] != -1; i++)
1828 if (!snd_register_ioport(card, possible_ports[i], 8,
1829 DRIVER_NAME" - WSS", NULL)) {
1830 port = possible_ports[i];
1831 break;
1832 }
1833 if (port == SNDRV_DEFAULT_PORT1)
1834 return -EBUSY;
1835 }
1836 else if ((error = snd_register_ioport(card, port, 8,
1837 DRIVER_NAME" - WSS", NULL)) < 0)
1838 return error;
1839 chip->chip->wss_base = port;
1840 if ((error = snd_register_interrupt(card, DRIVER_NAME" - WSS",
1841 irq, SNDRV_IRQ_TYPE_ISA,
1842 snd_card_opti9xx_interrupt, chip,
1843 pnp ? no_alternatives : possible_irqs,
1844 &chip->irqptr)) < 0)
1845 return error;
1846 chip->chip->irq = chip->irqptr->irq;
1847 if ((error = snd_register_dma_channel(card,
1848#if defined(CS4231) || defined(OPTi93X)
1849 DRIVER_NAME" - WSS playback",
1850#else
1851 DRIVER_NAME" - WSS",
1852#endif /* CS4231 || OPTi93X */
1853 dma1, SNDRV_DMA_TYPE_ISA, dma1_size,
1854 pnp ? no_alternatives : possible_dma1s,
1855 &chip->dma1ptr)) < 0)
1856 return error;
1857 chip->chip->dma1 = chip->dma1ptr->dma;
1858#if defined(CS4231) || defined(OPTi93X)
1859 if ((error = snd_register_dma_channel(card, DRIVER_NAME" - WSS capture",
1860 dma2, SNDRV_DMA_TYPE_ISA, dma2_size,
1861 pnp ? no_alternatives :
1862 possible_dma2s[chip->dma1ptr->dma],
1863 &chip->dma2ptr)) < 0)
1864 return error;
1865 chip->chip->dma2 = chip->dma2ptr->dma;
1866#endif /* CS4231 || OPTi93X */
1867
1868 if (snd_register_ioport(card,
1869 pnp ? fm_port : fm_port = 0x388, 4,
1870 DRIVER_NAME" - OPL", NULL) < 0)
1871 fm_port = -1;
1872 chip->chip->fm_port = fm_port;
1873
1874 return 0;
1875}
1876#endif
1877
1878static void snd_card_opti9xx_free(snd_card_t *card)
1879{
1880 opti9xx_t *chip = (opti9xx_t *)card->private_data;
1881
Takashi Iwaib1d57762005-10-10 11:56:31 +02001882 if (chip)
1883 release_and_free_resource(chip->res_mc_base);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001884}
1885
Takashi Iwai43bcd972005-09-05 17:19:20 +02001886static int snd_card_opti9xx_probe(struct pnp_card_link *pcard,
1887 const struct pnp_card_device_id *pid)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888{
1889 static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
1890 static long possible_mpu_ports[] = {0x300, 0x310, 0x320, 0x330, -1};
1891#ifdef OPTi93X
1892 static int possible_irqs[] = {5, 9, 10, 11, 7, -1};
1893#else
1894 static int possible_irqs[] = {9, 10, 11, 7, -1};
1895#endif /* OPTi93X */
1896 static int possible_mpu_irqs[] = {5, 9, 10, 7, -1};
1897 static int possible_dma1s[] = {3, 1, 0, -1};
1898#if defined(CS4231) || defined(OPTi93X)
1899 static int possible_dma2s[][2] = {{1,-1}, {0,-1}, {-1,-1}, {0,-1}};
1900#endif /* CS4231 || OPTi93X */
1901 int error;
1902 opti9xx_t *chip;
1903#if defined(OPTi93X)
1904 opti93x_t *codec;
1905#elif defined(CS4231)
1906 cs4231_t *codec;
1907 snd_timer_t *timer;
1908#else
1909 ad1848_t *codec;
1910#endif
1911 snd_card_t *card;
1912 snd_pcm_t *pcm;
1913 snd_rawmidi_t *rmidi;
1914 snd_hwdep_t *synth;
1915#ifdef CONFIG_PNP
1916 int hw;
1917#endif /* CONFIG_PNP */
1918
1919 if (pcard && !snd_opti9xx_first_hit)
1920 return -EBUSY;
1921 if (!(card = snd_card_new(index, id, THIS_MODULE,
1922 sizeof(opti9xx_t))))
1923 return -ENOMEM;
1924 card->private_free = snd_card_opti9xx_free;
1925 chip = (opti9xx_t *)card->private_data;
1926
1927#ifdef CONFIG_PNP
1928 if (isapnp && pcard && (hw = snd_card_opti9xx_pnp(chip, pcard, pid)) > 0) {
1929 switch (hw) {
1930 case 0x0924:
1931 hw = OPTi9XX_HW_82C924;
1932 break;
1933 case 0x0925:
1934 hw = OPTi9XX_HW_82C925;
1935 break;
1936 case 0x0931:
1937 hw = OPTi9XX_HW_82C931;
1938 break;
1939 default:
1940 snd_card_free(card);
1941 return -ENODEV;
1942 }
1943
1944 if ((error = snd_opti9xx_init(chip, hw))) {
1945 snd_card_free(card);
1946 return error;
1947 }
1948 if (hw <= OPTi9XX_HW_82C930)
1949 chip->mc_base -= 0x80;
1950 snd_card_set_dev(card, &pcard->card->dev);
1951 } else {
1952#endif /* CONFIG_PNP */
1953 if ((error = snd_card_opti9xx_detect(card, chip)) < 0) {
1954 snd_card_free(card);
1955 return error;
1956 }
Takashi Iwai43bcd972005-09-05 17:19:20 +02001957 if ((error = snd_card_set_generic_dev(card)) < 0) {
1958 snd_card_free(card);
1959 return error;
1960 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001961#ifdef CONFIG_PNP
1962 }
1963#endif /* CONFIG_PNP */
1964
1965 if (! chip->res_mc_base &&
1966 (chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size, "OPTi9xx MC")) == NULL) {
1967 snd_card_free(card);
1968 return -ENOMEM;
1969 }
1970
1971 chip->wss_base = port;
1972 chip->fm_port = fm_port;
1973 chip->mpu_port = mpu_port;
1974 chip->irq = irq;
1975 chip->mpu_irq = mpu_irq;
1976 chip->dma1 = dma1;
1977#if defined(CS4231) || defined(OPTi93X)
1978 chip->dma2 = dma2;
1979#endif
1980
1981 if (chip->wss_base == SNDRV_AUTO_PORT) {
1982 if ((chip->wss_base = snd_legacy_find_free_ioport(possible_ports, 4)) < 0) {
1983 snd_card_free(card);
1984 snd_printk("unable to find a free WSS port\n");
1985 return -EBUSY;
1986 }
1987 }
1988#ifdef CONFIG_PNP
1989 if (!isapnp) {
1990#endif
1991 if (chip->mpu_port == SNDRV_AUTO_PORT) {
1992 if ((chip->mpu_port = snd_legacy_find_free_ioport(possible_mpu_ports, 2)) < 0) {
1993 snd_card_free(card);
1994 snd_printk("unable to find a free MPU401 port\n");
1995 return -EBUSY;
1996 }
1997 }
1998 if (chip->irq == SNDRV_AUTO_IRQ) {
1999 if ((chip->irq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
2000 snd_card_free(card);
2001 snd_printk("unable to find a free IRQ\n");
2002 return -EBUSY;
2003 }
2004 }
2005 if (chip->mpu_irq == SNDRV_AUTO_IRQ) {
2006 if ((chip->mpu_irq = snd_legacy_find_free_irq(possible_mpu_irqs)) < 0) {
2007 snd_card_free(card);
2008 snd_printk("unable to find a free MPU401 IRQ\n");
2009 return -EBUSY;
2010 }
2011 }
2012 if (chip->dma1 == SNDRV_AUTO_DMA) {
2013 if ((chip->dma1 = snd_legacy_find_free_dma(possible_dma1s)) < 0) {
2014 snd_card_free(card);
2015 snd_printk("unable to find a free DMA1\n");
2016 return -EBUSY;
2017 }
2018 }
2019#if defined(CS4231) || defined(OPTi93X)
2020 if (chip->dma2 == SNDRV_AUTO_DMA) {
2021 if ((chip->dma2 = snd_legacy_find_free_dma(possible_dma2s[chip->dma1 % 4])) < 0) {
2022 snd_card_free(card);
2023 snd_printk("unable to find a free DMA2\n");
2024 return -EBUSY;
2025 }
2026 }
2027#endif
2028
2029#ifdef CONFIG_PNP
2030 }
2031#endif
2032
2033 if ((error = snd_opti9xx_configure(chip))) {
2034 snd_card_free(card);
2035 return error;
2036 }
2037
2038#if defined(OPTi93X)
2039 if ((error = snd_opti93x_create(card, chip, chip->dma1, chip->dma2, &codec))) {
2040 snd_card_free(card);
2041 return error;
2042 }
2043 if ((error = snd_opti93x_pcm(codec, 0, &pcm)) < 0) {
2044 snd_card_free(card);
2045 return error;
2046 }
2047 if ((error = snd_opti93x_mixer(codec)) < 0) {
2048 snd_card_free(card);
2049 return error;
2050 }
2051#elif defined(CS4231)
2052 if ((error = snd_cs4231_create(card, chip->wss_base + 4, -1,
2053 chip->irq, chip->dma1, chip->dma2,
2054 CS4231_HW_DETECT,
2055 0,
2056 &codec)) < 0) {
2057 snd_card_free(card);
2058 return error;
2059 }
2060 if ((error = snd_cs4231_pcm(codec, 0, &pcm)) < 0) {
2061 snd_card_free(card);
2062 return error;
2063 }
2064 if ((error = snd_cs4231_mixer(codec)) < 0) {
2065 snd_card_free(card);
2066 return error;
2067 }
2068 if ((error = snd_cs4231_timer(codec, 0, &timer)) < 0) {
2069 snd_card_free(card);
2070 return error;
2071 }
2072#else
2073 if ((error = snd_ad1848_create(card, chip->wss_base + 4,
2074 chip->irq, chip->dma1,
2075 AD1848_HW_DETECT, &codec)) < 0) {
2076 snd_card_free(card);
2077 return error;
2078 }
2079 if ((error = snd_ad1848_pcm(codec, 0, &pcm)) < 0) {
2080 snd_card_free(card);
2081 return error;
2082 }
2083 if ((error = snd_ad1848_mixer(codec)) < 0) {
2084 snd_card_free(card);
2085 return error;
2086 }
2087#endif
2088 strcpy(card->driver, chip->name);
2089 sprintf(card->shortname, "OPTi %s", card->driver);
2090#if defined(CS4231) || defined(OPTi93X)
2091 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d",
2092 card->shortname, pcm->name, chip->wss_base + 4,
2093 chip->irq, chip->dma1, chip->dma2);
2094#else
2095 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d",
2096 card->shortname, pcm->name, chip->wss_base + 4,
2097 chip->irq, chip->dma1);
2098#endif /* CS4231 || OPTi93X */
2099
2100 if (chip->mpu_port <= 0 || chip->mpu_port == SNDRV_AUTO_PORT)
2101 rmidi = NULL;
2102 else
2103 if ((error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
2104 chip->mpu_port, 0, chip->mpu_irq, SA_INTERRUPT,
2105 &rmidi)))
2106 snd_printk("no MPU-401 device at 0x%lx?\n", chip->mpu_port);
2107
2108 if (chip->fm_port > 0 && chip->fm_port != SNDRV_AUTO_PORT) {
2109 opl3_t *opl3 = NULL;
2110#ifndef OPTi93X
2111 if (chip->hardware == OPTi9XX_HW_82C928 ||
2112 chip->hardware == OPTi9XX_HW_82C929 ||
2113 chip->hardware == OPTi9XX_HW_82C924) {
2114 opl4_t *opl4;
2115 /* assume we have an OPL4 */
2116 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2),
2117 0x20, 0x20);
2118 if (snd_opl4_create(card,
2119 chip->fm_port,
2120 chip->fm_port - 8,
2121 2, &opl3, &opl4) < 0) {
2122 /* no luck, use OPL3 instead */
2123 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2),
2124 0x00, 0x20);
2125 }
2126 }
2127#endif /* !OPTi93X */
2128 if (!opl3 && snd_opl3_create(card,
2129 chip->fm_port,
2130 chip->fm_port + 2,
2131 OPL3_HW_AUTO, 0, &opl3) < 0) {
2132 snd_printk("no OPL device at 0x%lx-0x%lx\n",
2133 chip->fm_port, chip->fm_port + 4 - 1);
2134 }
2135 if (opl3) {
2136 if ((error = snd_opl3_timer_new(opl3,
2137#ifdef CS4231
2138 1, 2)) < 0) {
2139#else
2140 0, 1)) < 0) {
2141#endif /* CS4231 */
2142 snd_card_free(card);
2143 return error;
2144 }
2145 if ((error = snd_opl3_hwdep_new(opl3, 0, 1, &synth)) < 0) {
2146 snd_card_free(card);
2147 return error;
2148 }
2149 }
2150 }
2151
2152 if ((error = snd_card_register(card))) {
2153 snd_card_free(card);
2154 return error;
2155 }
2156 snd_opti9xx_first_hit = 0;
2157 if (pcard)
2158 pnp_set_card_drvdata(pcard, card);
2159 else
2160 snd_opti9xx_legacy = card;
2161 return 0;
2162}
2163
2164#ifdef CONFIG_PNP
2165static void __devexit snd_opti9xx_pnp_remove(struct pnp_card_link * pcard)
2166{
2167 snd_card_t *card = (snd_card_t *) pnp_get_card_drvdata(pcard);
2168
2169 snd_card_disconnect(card);
2170 snd_card_free_in_thread(card);
2171 snd_opti9xx_first_hit = 0;
2172}
2173
2174static struct pnp_card_driver opti9xx_pnpc_driver = {
2175 .flags = PNP_DRIVER_RES_DISABLE,
2176 .name = "opti9xx",
2177 .id_table = snd_opti9xx_pnpids,
2178 .probe = snd_card_opti9xx_probe,
2179 .remove = __devexit_p(snd_opti9xx_pnp_remove),
2180};
2181#endif
2182
2183static int __init alsa_card_opti9xx_init(void)
2184{
2185 int cards, error;
2186
2187#ifdef CONFIG_PNP
2188 cards = pnp_register_card_driver(&opti9xx_pnpc_driver);
2189#else
2190 cards = 0;
2191#endif
2192 if (cards == 0 && (error = snd_card_opti9xx_probe(NULL, NULL)) < 0) {
2193#ifdef CONFIG_PNP
2194 pnp_unregister_card_driver(&opti9xx_pnpc_driver);
2195#endif
2196#ifdef MODULE
2197#ifdef OPTi93X
2198 printk(KERN_ERR "no OPTi 82C93x soundcard found\n");
2199#else
2200 printk(KERN_ERR "no OPTi 82C92x soundcard found\n");
2201#endif /* OPTi93X */
2202#endif
2203 return error;
2204 }
2205 return 0;
2206}
2207
2208static void __exit alsa_card_opti9xx_exit(void)
2209{
2210#ifdef CONFIG_PNP
2211 pnp_unregister_card_driver(&opti9xx_pnpc_driver);
2212#endif
2213 if (snd_opti9xx_legacy)
2214 snd_card_free(snd_opti9xx_legacy);
2215}
2216
2217module_init(alsa_card_opti9xx_init)
2218module_exit(alsa_card_opti9xx_exit)