Linux 2.2.0
[davej-history.git] / drivers / sound / ad1816.c
blob6d7c2e13e1d2346538fb28dda5eb404d112eb039
1 /*
3 AD1816 lowlevel sound driver for Linux 2.2.0 and above
5 Copyright (C) 1998 by Thorsten Knabe <tek@rbg.informatik.tu-darmstadt.de>
6 Based on the CS4232/AD1848 driver Copyright (C) by Hannu Savolainen 1993-1996
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
22 -------------------------------------------------------------------------------
23 NOTE! NOTE! NOTE! NOTE! NOTE! NOTE! NOTE! NOTE! NOTE!
25 This software is still under development. New versions of the driver
26 are available from:
27 http://www.student.informatik.tu-darmstadt.de/~tek/projects/linux.html
29 http://www.tu-darmstadt.de/~tek01/projects/linux.html
31 Please report any bugs to: tek@rbg.informatik.tu-darmstadt.de
33 -------------------------------------------------------------------------------
35 version: 1.2
36 cvs: $Header: /home/tek/tmp/CVSROOT/sound21/ad1816.c,v 1.28 1999/01/16 19:01:36 tek Exp $
37 status: experimental
38 date: 1999/01/16
40 Changes:
41 Oleg Drokin: Some cleanup of load/unload functions. 1998/11/24
43 Thorsten Knabe: attach and unload rewritten,
44 some argument checks added 1998/11/30
46 Thorsten Knabe: Buggy isa bridge workaround added 1999/01/16
49 #include <linux/config.h>
50 #include <linux/module.h>
51 #include <linux/stddef.h>
52 #include "soundmodule.h"
53 #include "sound_config.h"
55 #ifdef CONFIG_AD1816
57 #define DEBUGNOISE(x)
58 #define DEBUGINFO(x)
59 #define DEBUGLOG(x) x
60 #define DEBUGWARN(x) x
62 #define CHECK_FOR_POWER { int timeout=100; \
63 while (timeout > 0 && (inb(devc->base)&0x80)!= 0x80) {\
64 timeout--; \
65 } \
66 if (timeout==0) {\
67 printk("ad1816: Check for power failed in %s line: %d\n",__FILE__,__LINE__); \
68 } \
71 /* structure to hold device specific information */
72 typedef struct
74 int base; /* set in attach */
75 int irq;
76 int dma_playback;
77 int dma_capture;
79 int speed; /* open */
80 int channels;
81 int audio_format;
82 unsigned char format_bits;
83 int audio_mode;
84 int opened;
86 int recmask; /* setup */
87 int supported_devices;
88 int supported_rec_devices;
89 unsigned short levels[SOUND_MIXER_NRDEVICES];
90 int dev_no; /* this is the # in audio_devs and NOT
91 in ad1816_info */
92 int irq_ok;
93 int *osp;
97 ad1816_info;
99 static int nr_ad1816_devs = 0;
101 static int ad1816_clockfreq=33000;
103 /* for backward mapping of irq to sound device */
105 static volatile char irq2dev[17] = {-1, -1, -1, -1, -1, -1, -1, -1,
106 -1, -1, -1, -1, -1, -1, -1, -1, -1};
109 /* supported audio formats */
110 static int ad_format_mask =
111 AFMT_U8 | AFMT_S16_LE | AFMT_S16_BE | AFMT_MU_LAW | AFMT_A_LAW;
113 /* array of device info structures */
114 static ad1816_info dev_info[MAX_AUDIO_DEV];
117 /* ------------------------------------------------------------------- */
119 /* functions for easier access to inderect registers */
121 static int ad_read (ad1816_info * devc, int reg)
123 unsigned long flags;
124 int result;
126 CHECK_FOR_POWER;
128 save_flags (flags); /* make register access atomic */
129 cli ();
130 outb ((unsigned char) (reg & 0x3f), devc->base+0);
131 result = inb(devc->base+2);
132 result+= inb(devc->base+3)<<8;
133 restore_flags (flags);
135 return (result);
139 static void ad_write (ad1816_info * devc, int reg, int data)
141 unsigned long flags;
143 CHECK_FOR_POWER;
145 save_flags (flags); /* make register access atomic */
146 cli ();
147 outb ((unsigned char) (reg & 0xff), devc->base+0);
148 outb ((unsigned char) (data & 0xff),devc->base+2);
149 outb ((unsigned char) ((data>>8)&0xff),devc->base+3);
150 restore_flags (flags);
154 /* ------------------------------------------------------------------- */
156 /* function interface required by struct audio_driver */
158 static void ad1816_halt_input (int dev)
160 unsigned long flags;
161 ad1816_info *devc = (ad1816_info *) audio_devs[dev]->devc;
162 unsigned char buffer;
164 DEBUGINFO (printk("ad1816: halt_input called\n"));
166 save_flags (flags);
167 cli ();
169 if(!isa_dma_bridge_buggy) {
170 disable_dma(audio_devs[dev]->dmap_in->dma);
173 buffer=inb(devc->base+9);
174 if (buffer & 0x01) {
175 /* disable capture */
176 outb(buffer & ~0x01,devc->base+9);
179 if(!isa_dma_bridge_buggy) {
180 enable_dma(audio_devs[dev]->dmap_in->dma);
183 /* Clear interrupt status */
184 outb (~0x40, devc->base+1);
186 devc->audio_mode &= ~PCM_ENABLE_INPUT;
187 restore_flags (flags);
190 static void ad1816_halt_output (int dev)
192 unsigned long flags;
193 ad1816_info *devc = (ad1816_info *) audio_devs[dev]->devc;
195 unsigned char buffer;
197 DEBUGINFO (printk("ad1816: halt_output called!\n"));
199 save_flags (flags);
200 cli ();
201 /* Mute pcm output */
202 ad_write(devc, 4, ad_read(devc,4)|0x8080);
204 if(!isa_dma_bridge_buggy) {
205 disable_dma(audio_devs[dev]->dmap_out->dma);
208 buffer=inb(devc->base+8);
209 if (buffer & 0x01) {
210 /* disable capture */
211 outb(buffer & ~0x01,devc->base+8);
214 if(!isa_dma_bridge_buggy) {
215 enable_dma(audio_devs[dev]->dmap_out->dma);
218 /* Clear interrupt status */
219 outb ((unsigned char)~0x80, devc->base+1);
221 devc->audio_mode &= ~PCM_ENABLE_OUTPUT;
222 restore_flags (flags);
225 static void ad1816_output_block (int dev, unsigned long buf,
226 int count, int intrflag)
228 unsigned long flags;
229 unsigned long cnt;
230 ad1816_info *devc = (ad1816_info *) audio_devs[dev]->devc;
232 DEBUGINFO(printk("ad1816: output_block called buf=%ld count=%d flags=%d\n",buf,count,intrflag));
234 cnt = count/4 - 1;
236 save_flags (flags);
237 cli ();
239 /* set transfer count */
240 ad_write (devc, 8, cnt & 0xffff);
242 devc->audio_mode |= PCM_ENABLE_OUTPUT;
243 restore_flags (flags);
247 static void ad1816_start_input (int dev, unsigned long buf, int count,
248 int intrflag)
250 unsigned long flags;
251 unsigned long cnt;
252 ad1816_info *devc = (ad1816_info *) audio_devs[dev]->devc;
254 DEBUGINFO(printk("ad1816: start_input called buf=%ld count=%d flags=%d\n",buf,count,intrflag));
256 cnt = count/4 - 1;
258 save_flags (flags); /* make register access atomic */
259 cli ();
261 /* set transfer count */
262 ad_write (devc, 10, cnt & 0xffff);
264 devc->audio_mode |= PCM_ENABLE_INPUT;
265 restore_flags (flags);
269 static int ad1816_ioctl (int dev, unsigned int cmd, caddr_t arg)
271 return -(EINVAL);
275 static int ad1816_prepare_for_input (int dev, int bsize, int bcount)
277 unsigned long flags;
278 unsigned int freq;
279 ad1816_info *devc = (ad1816_info *) audio_devs[dev]->devc;
280 unsigned char fmt_bits;
282 DEBUGINFO (printk ("ad1816: prepare_for_input called: bsize=%d bcount=%d\n",bsize,bcount));
284 save_flags (flags);
285 cli ();
287 fmt_bits= (devc->format_bits&0x7)<<3;
289 /* set mono/stereo mode */
290 if (devc->channels > 1) {
291 fmt_bits |=0x4;
294 /* set Mono/Stereo in playback/capture register */
295 outb( (inb(devc->base+8) & ~0x3C)|fmt_bits, devc->base+8);
296 outb( (inb(devc->base+9) & ~0x3C)|fmt_bits, devc->base+9);
298 /* If compiled into kernel, AD1816_CLOCK is defined, so use it */
299 #ifdef AD1816_CLOCK
300 ad1816_clockfreq=AD1816_CLOCK;
301 #endif
303 /* capture/playback frequency correction for soundcards
304 with clock chips != 33MHz (allowed range 5 - 100 kHz) */
306 if (ad1816_clockfreq<5000 || ad1816_clockfreq>100000) {
307 ad1816_clockfreq=33000;
310 freq=((unsigned int)devc->speed*33000)/ad1816_clockfreq;
312 /* write playback/capture speeds */
313 ad_write (devc, 2, freq & 0xffff);
314 ad_write (devc, 3, freq & 0xffff);
316 restore_flags (flags);
318 ad1816_halt_input(dev);
319 return 0;
322 static int ad1816_prepare_for_output (int dev, int bsize, int bcount)
324 unsigned long flags;
325 unsigned int freq;
326 ad1816_info *devc = (ad1816_info *) audio_devs[dev]->devc;
327 unsigned char fmt_bits;
329 DEBUGINFO (printk ("ad1816: prepare_for_output called: bsize=%d bcount=%d\n",bsize,bcount));
331 save_flags (flags); /* make register access atomic */
332 cli ();
334 fmt_bits= (devc->format_bits&0x7)<<3;
335 /* set mono/stereo mode */
336 if (devc->channels > 1) {
337 fmt_bits |=0x4;
340 /* write format bits to playback/capture registers */
341 outb( (inb(devc->base+8) & ~0x3C)|fmt_bits, devc->base+8);
342 outb( (inb(devc->base+9) & ~0x3C)|fmt_bits, devc->base+9);
344 #ifdef AD1816_CLOCK
345 ad1816_clockfreq=AD1816_CLOCK;
346 #endif
348 /* capture/playback frequency correction for soundcards
349 with clock chips != 33MHz (allowed range 5 - 100 kHz)*/
351 if (ad1816_clockfreq<5000 || ad1816_clockfreq>100000) {
352 ad1816_clockfreq=33000;
355 freq=((unsigned int)devc->speed*33000)/ad1816_clockfreq;
357 /* write playback/capture speeds */
358 ad_write (devc, 2, freq & 0xffff);
359 ad_write (devc, 3, freq & 0xffff);
361 restore_flags (flags);
363 ad1816_halt_output(dev);
364 return 0;
368 static void ad1816_trigger (int dev, int state)
370 unsigned long flags;
371 ad1816_info *devc = (ad1816_info *) audio_devs[dev]->devc;
373 DEBUGINFO (printk("ad1816: trigger called! (devc=%d,devc->base=%d\n",devc,devc->base));
375 /* mode may have changed */
377 save_flags (flags); /* make register access atomic */
378 cli ();
380 /* mask out modes not specified on open call */
381 state &= devc->audio_mode;
383 /* setup soundchip to new io-mode */
384 if (state & PCM_ENABLE_INPUT) {
385 /* enable capture */
386 outb(inb(devc->base+9)|0x01, devc->base+9);
387 } else {
388 /* disable capture */
389 outb(inb(devc->base+9)&~0x01, devc->base+9);
392 if (state & PCM_ENABLE_OUTPUT) {
393 /* enable playback */
394 outb(inb(devc->base+8)|0x01, devc->base+8);
395 /* unmute pcm output */
396 ad_write(devc, 4, ad_read(devc,4)&~0x8080);
397 } else {
398 /* mute pcm output */
399 ad_write(devc, 4, ad_read(devc,4)|0x8080);
400 /* disable capture */
401 outb(inb(devc->base+8)&~0x01, devc->base+8);
403 restore_flags (flags);
407 /* halt input & output */
408 static void ad1816_halt (int dev)
410 ad1816_halt_input(dev);
411 ad1816_halt_output(dev);
414 static void ad1816_reset (int dev)
416 ad1816_halt (dev);
419 /* set playback speed */
420 static int ad1816_set_speed (int dev, int arg)
422 ad1816_info *devc = (ad1816_info *) audio_devs[dev]->devc;
424 if (arg == 0) {
425 return devc->speed;
427 /* range checking */
428 if (arg < 4000) {
429 arg = 4000;
431 if (arg > 55000) {
432 arg = 55000;
435 devc->speed = arg;
436 return devc->speed;
440 static unsigned int ad1816_set_bits (int dev, unsigned int arg)
442 ad1816_info *devc = (ad1816_info *) audio_devs[dev]->devc;
444 static struct format_tbl
446 int format;
447 unsigned char bits;
449 format2bits[] =
452 0, 0
456 AFMT_MU_LAW, 1
460 AFMT_A_LAW, 3
464 AFMT_IMA_ADPCM, 0
468 AFMT_U8, 0
472 AFMT_S16_LE, 2
476 AFMT_S16_BE, 6
480 AFMT_S8, 0
484 AFMT_U16_LE, 0
488 AFMT_U16_BE, 0
491 int i, n = sizeof (format2bits) / sizeof (struct format_tbl);
493 /* return current format */
494 if (arg == 0) {
495 return devc->audio_format;
498 devc->audio_format = arg;
500 /* search matching format bits */
501 for (i = 0; i < n; i++) {
502 if (format2bits[i].format == arg) {
503 devc->format_bits = format2bits[i].bits;
504 devc->audio_format = arg;
505 return arg;
508 /* Still hanging here. Something must be terribly wrong */
509 devc->format_bits = 0;
510 return devc->audio_format = AFMT_U8;
513 static short ad1816_set_channels (int dev, short arg)
515 ad1816_info *devc = (ad1816_info *) audio_devs[dev]->devc;
517 if (arg != 1 && arg != 2) {
518 return devc->channels;
521 devc->channels = arg;
522 return arg;
525 /* open device */
526 static int ad1816_open (int dev, int mode)
528 ad1816_info *devc = NULL;
529 unsigned long flags;
531 /* is device number valid ? */
532 if (dev < 0 || dev >= num_audiodevs) {
533 return -(ENXIO);
536 /* get device info of this dev */
537 devc = (ad1816_info *) audio_devs[dev]->devc;
539 /* make check if device already open atomic */
540 save_flags (flags);
541 cli ();
543 if (devc->opened) {
544 restore_flags (flags);
545 return -(EBUSY);
548 /* mark device as open */
549 devc->opened = 1;
551 devc->audio_mode = 0;
552 devc->speed = 8000;
553 devc->audio_format=AFMT_U8;
554 devc->channels=1;
556 ad1816_reset(devc->dev_no); /* halt all pending output */
557 restore_flags (flags);
558 return 0;
561 static void ad1816_close (int dev) /* close device */
563 unsigned long flags;
564 ad1816_info *devc = (ad1816_info *) audio_devs[dev]->devc;
566 save_flags (flags);
567 cli ();
569 /* halt all pending output */
570 ad1816_reset(devc->dev_no);
572 devc->opened = 0;
573 devc->audio_mode = 0;
574 devc->speed = 8000;
575 devc->audio_format=AFMT_U8;
576 devc->format_bits = 0;
579 restore_flags (flags);
583 /* ------------------------------------------------------------------- */
585 /* Audio driver structure */
587 static struct audio_driver ad1816_audio_driver =
589 ad1816_open,
590 ad1816_close,
591 ad1816_output_block,
592 ad1816_start_input,
593 ad1816_ioctl,
594 ad1816_prepare_for_input,
595 ad1816_prepare_for_output,
596 ad1816_halt,
597 NULL,
598 NULL,
599 ad1816_halt_input,
600 ad1816_halt_output,
601 ad1816_trigger,
602 ad1816_set_speed,
603 ad1816_set_bits,
604 ad1816_set_channels,
605 NULL,
606 NULL
610 /* ------------------------------------------------------------------- */
612 /* Interrupt handler */
614 void ad1816_interrupt (int irq, void *dev_id, struct pt_regs *dummy)
616 unsigned char status;
617 ad1816_info *devc;
618 int dev;
619 unsigned long flags;
622 if (irq < 0 || irq > 15) {
623 printk ("ad1816: Got bogus interrupt %d\n", irq);
624 return;
627 dev = irq2dev[irq];
629 if (dev < 0 || dev >= num_audiodevs) {
630 printk ("ad1816: IRQ2AD1816-mapping failed for irq %d device %d\n", irq,dev);
631 return;
634 devc = (ad1816_info *) audio_devs[dev]->devc;
636 save_flags(flags);
637 cli();
639 /* read interrupt register */
640 status = inb (devc->base+1);
641 /* Clear all interrupt */
642 outb (~status, devc->base+1);
644 DEBUGNOISE (printk("ad1816: Got interrupt subclass %d\n",status));
646 devc->irq_ok=1;
648 if (status == 0) {
649 DEBUGWARN(printk ("ad1816: interrupt: Got interrupt, but no reason?\n"));
651 if (devc->opened && (devc->audio_mode & PCM_ENABLE_INPUT)
652 && (status&64)){
653 DMAbuf_inputintr (dev);
656 if (devc->opened && (devc->audio_mode & PCM_ENABLE_OUTPUT) &&
657 (status & 128)) {
658 DMAbuf_outputintr (dev, 1);
660 restore_flags(flags);
663 /* ------------------------------------------------------------------- */
665 /* Mixer stuff */
667 struct mixer_def {
668 unsigned int regno: 7;
669 unsigned int polarity:1; /* 0=normal, 1=reversed */
670 unsigned int bitpos:4;
671 unsigned int nbits:4;
674 static char mix_cvt[101] = {
675 0, 0,3,7,10,13,16,19,21,23,26,28,30,32,34,35,37,39,40,42,
676 43,45,46,47,49,50,51,52,53,55,56,57,58,59,60,61,62,63,64,65,
677 65,66,67,68,69,70,70,71,72,73,73,74,75,75,76,77,77,78,79,79,
678 80,81,81,82,82,83,84,84,85,85,86,86,87,87,88,88,89,89,90,90,
679 91,91,92,92,93,93,94,94,95,95,96,96,96,97,97,98,98,98,99,99,
683 typedef struct mixer_def mixer_ent;
686 * Most of the mixer entries work in backwards. Setting the polarity field
687 * makes them to work correctly.
689 * The channel numbering used by individual soundcards is not fixed. Some
690 * cards have assigned different meanings for the AUX1, AUX2 and LINE inputs.
691 * The current version doesn't try to compensate this.
694 #define MIX_ENT(name, reg_l, pola_l, pos_l, len_l, reg_r, pola_r, pos_r, len_r) \
695 {{reg_l, pola_l, pos_l, len_l}, {reg_r, pola_r, pos_r, len_r}}
698 mixer_ent mix_devices[SOUND_MIXER_NRDEVICES][2] = {
699 MIX_ENT(SOUND_MIXER_VOLUME, 14, 1, 8, 5, 14, 1, 0, 5),
700 MIX_ENT(SOUND_MIXER_BASS, 0, 0, 0, 0, 0, 0, 0, 0),
701 MIX_ENT(SOUND_MIXER_TREBLE, 0, 0, 0, 0, 0, 0, 0, 0),
702 MIX_ENT(SOUND_MIXER_SYNTH, 5, 1, 8, 6, 5, 1, 0, 6),
703 MIX_ENT(SOUND_MIXER_PCM, 4, 1, 8, 6, 4, 1, 0, 6),
704 MIX_ENT(SOUND_MIXER_SPEAKER, 0, 0, 0, 0, 0, 0, 0, 0),
705 MIX_ENT(SOUND_MIXER_LINE, 18, 1, 8, 5, 18, 1, 0, 5),
706 MIX_ENT(SOUND_MIXER_MIC, 19, 1, 8, 5, 19, 1, 0, 5),
707 MIX_ENT(SOUND_MIXER_CD, 15, 1, 8, 5, 15, 1, 0, 5),
708 MIX_ENT(SOUND_MIXER_IMIX, 0, 0, 0, 0, 0, 0, 0, 0),
709 MIX_ENT(SOUND_MIXER_ALTPCM, 0, 0, 0, 0, 0, 0, 0, 0),
710 MIX_ENT(SOUND_MIXER_RECLEV, 20, 0, 8, 4, 20, 0, 0, 4),
711 MIX_ENT(SOUND_MIXER_IGAIN, 0, 0, 0, 0, 0, 0, 0, 0),
712 MIX_ENT(SOUND_MIXER_OGAIN, 0, 0, 0, 0, 0, 0, 0, 0),
713 MIX_ENT(SOUND_MIXER_LINE1, 17, 1, 8, 5, 17, 1, 0, 5),
714 MIX_ENT(SOUND_MIXER_LINE2, 16, 1, 8, 5, 16, 1, 0, 5),
715 MIX_ENT(SOUND_MIXER_LINE3, 39, 0, 9, 4, 39, 1, 0, 5)
719 static unsigned short default_mixer_levels[SOUND_MIXER_NRDEVICES] =
721 0x4343, /* Master Volume */
722 0x3232, /* Bass */
723 0x3232, /* Treble */
724 0x0000, /* FM */
725 0x4343, /* PCM */
726 0x0000, /* PC Speaker */
727 0x0000, /* Ext Line */
728 0x0000, /* Mic */
729 0x0000, /* CD */
730 0x0000, /* Recording monitor */
731 0x0000, /* SB PCM */
732 0x0000, /* Recording level */
733 0x0000, /* Input gain */
734 0x0000, /* Output gain */
735 0x0000, /* Line1 */
736 0x0000, /* Line2 */
737 0x0000 /* Line3 (usually line in)*/
740 #define LEFT_CHN 0
741 #define RIGHT_CHN 1
745 static int
746 ad1816_set_recmask (ad1816_info * devc, int mask)
748 unsigned char recdev;
749 int i, n;
751 mask &= devc->supported_rec_devices;
753 n = 0;
754 /* Count selected device bits */
755 for (i = 0; i < 32; i++) {
756 if (mask & (1 << i)) {
757 n++;
761 if (n == 0) {
762 mask = SOUND_MASK_MIC;
763 } else if (n != 1) { /* Too many devices selected */
764 /* Filter out active settings */
765 mask &= ~devc->recmask;
767 n = 0;
768 /* Count selected device bits */
769 for (i = 0; i < 32; i++) {
770 if (mask & (1 << i)) {
771 n++;
775 if (n != 1) {
776 mask = SOUND_MASK_MIC;
780 switch (mask) {
781 case SOUND_MASK_MIC:
782 recdev = 5;
783 break;
785 case SOUND_MASK_LINE:
786 recdev = 0;
787 break;
789 case SOUND_MASK_CD:
790 recdev = 2;
791 break;
793 case SOUND_MASK_LINE1:
794 recdev = 4;
795 break;
797 case SOUND_MASK_LINE2:
798 recdev = 3;
799 break;
801 case SOUND_MASK_VOLUME:
802 recdev = 1;
803 break;
805 default:
806 mask = SOUND_MASK_MIC;
807 recdev = 5;
810 recdev <<= 4;
811 ad_write (devc, 20,
812 (ad_read (devc, 20) & 0x8f8f) | recdev | (recdev<<8));
814 devc->recmask = mask;
815 return mask;
818 static void
819 change_bits (int *regval, int dev, int chn, int newval)
821 unsigned char mask;
822 int shift;
824 /* Reverse polarity*/
826 if (mix_devices[dev][chn].polarity == 1) {
827 newval = 100 - newval;
830 mask = (1 << mix_devices[dev][chn].nbits) - 1;
831 shift = mix_devices[dev][chn].bitpos;
832 /* Scale it */
833 newval = (int) ((newval * mask) + 50) / 100;
834 /* Clear bits */
835 *regval &= ~(mask << shift);
836 /* Set new value */
837 *regval |= (newval & mask) << shift;
840 static int
841 ad1816_mixer_get (ad1816_info * devc, int dev)
843 DEBUGINFO(printk("ad1816: mixer_get called!\n"));
845 /* range check + supported mixer check */
846 if (dev < 0 || dev >= SOUND_MIXER_NRDEVICES ) {
847 return (-(EINVAL));
849 if (!((1 << dev) & devc->supported_devices)) {
850 return -(EINVAL);
853 return devc->levels[dev];
856 static int
857 ad1816_mixer_set (ad1816_info * devc, int dev, int value)
859 int left = value & 0x000000ff;
860 int right = (value & 0x0000ff00) >> 8;
861 int retvol;
863 int regoffs;
864 int val;
865 int valmute;
867 DEBUGINFO(printk("ad1816: mixer_set called!\n"));
869 if (dev < 0 || dev >= SOUND_MIXER_NRDEVICES ) {
870 return -(EINVAL);
873 if (left > 100) {
874 left = 100;
876 if (left < 0) {
877 left = 0;
879 if (right > 100) {
880 right = 100;
882 if (right < 0) {
883 right = 0;
886 /* Mono control */
887 if (mix_devices[dev][RIGHT_CHN].nbits == 0) {
888 right = left;
890 retvol = left | (right << 8);
892 /* Scale it */
894 left = mix_cvt[left];
895 right = mix_cvt[right];
897 /* reject all mixers that are not supported */
898 if (!(devc->supported_devices & (1 << dev))) {
899 return -(EINVAL);
902 /* sanity check */
903 if (mix_devices[dev][LEFT_CHN].nbits == 0) {
904 return -(EINVAL);
907 /* keep precise volume internal */
908 devc->levels[dev] = retvol;
910 /* Set the left channel */
911 regoffs = mix_devices[dev][LEFT_CHN].regno;
912 val = ad_read (devc, regoffs);
913 change_bits (&val, dev, LEFT_CHN, left);
915 valmute=val;
917 /* Mute bit masking on some registers */
918 if ( regoffs==5 || regoffs==14 || regoffs==15 ||
919 regoffs==16 || regoffs==17 || regoffs==18 ||
920 regoffs==19 || regoffs==39) {
921 if (left==0) {
922 valmute |= 0x8000;
923 } else {
924 valmute &= ~0x8000;
927 ad_write (devc, regoffs, valmute); /* mute */
930 * Set the right channel
933 /* Was just a mono channel */
934 if (mix_devices[dev][RIGHT_CHN].nbits == 0) {
935 return retvol;
937 regoffs = mix_devices[dev][RIGHT_CHN].regno;
938 val = ad_read (devc, regoffs);
939 change_bits (&val, dev, RIGHT_CHN, right);
941 valmute=val;
942 if ( regoffs==5 || regoffs==14 || regoffs==15 ||
943 regoffs==16 || regoffs==17 || regoffs==18 ||
944 regoffs==19 || regoffs==39) {
945 if (right==0) {
946 valmute |= 0x80;
947 } else {
948 valmute &= ~0x80;
951 ad_write (devc, regoffs, valmute); /* mute */
953 return retvol;
956 #define MIXER_DEVICES ( SOUND_MASK_VOLUME | \
957 SOUND_MASK_SYNTH | \
958 SOUND_MASK_PCM | \
959 SOUND_MASK_LINE | \
960 SOUND_MASK_LINE1 | \
961 SOUND_MASK_LINE2 | \
962 SOUND_MASK_LINE3 | \
963 SOUND_MASK_MIC | \
964 SOUND_MASK_CD | \
965 SOUND_MASK_RECLEV \
967 #define REC_DEVICES ( SOUND_MASK_LINE2 |\
968 SOUND_MASK_LINE |\
969 SOUND_MASK_LINE1 |\
970 SOUND_MASK_MIC |\
971 SOUND_MASK_CD |\
972 SOUND_MASK_VOLUME \
975 static void
976 ad1816_mixer_reset (ad1816_info * devc)
978 int i;
980 devc->supported_devices = MIXER_DEVICES;
982 devc->supported_rec_devices = REC_DEVICES;
984 for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
985 if (devc->supported_devices & (1 << i)) {
986 ad1816_mixer_set (devc, i, default_mixer_levels[i]);
989 ad1816_set_recmask (devc, SOUND_MASK_MIC);
992 static int
993 ad1816_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg)
995 ad1816_info *devc = mixer_devs[dev]->devc;
996 int val;
998 DEBUGINFO(printk("ad1816: mixer_ioctl called!\n"));
1000 /* Mixer ioctl */
1001 if (((cmd >> 8) & 0xff) == 'M') {
1003 /* set ioctl */
1004 if (_IOC_DIR (cmd) & _IOC_WRITE) {
1005 switch (cmd & 0xff){
1006 case SOUND_MIXER_RECSRC:
1008 if (get_user(val, (int *)arg)) {
1009 return -EFAULT;
1011 val=ad1816_set_recmask (devc, val);
1012 return put_user(val, (int *)arg);
1013 break;
1015 default:
1016 if (get_user(val, (int *)arg)){
1017 return -EFAULT;
1019 if ((val=ad1816_mixer_set (devc, cmd & 0xff, val))<0) {
1020 return val;
1021 } else {
1022 return put_user(val, (int *)arg);
1025 } else {
1026 /* read ioctl */
1027 switch (cmd & 0xff) {
1029 case SOUND_MIXER_RECSRC:
1030 val=devc->recmask;
1031 return put_user(val, (int *)arg);
1032 break;
1034 case SOUND_MIXER_DEVMASK:
1035 val=devc->supported_devices;
1036 return put_user(val, (int *)arg);
1037 break;
1039 case SOUND_MIXER_STEREODEVS:
1040 val=devc->supported_devices & ~(SOUND_MASK_SPEAKER | SOUND_MASK_IMIX);
1041 return put_user(val, (int *)arg);
1042 break;
1044 case SOUND_MIXER_RECMASK:
1045 val=devc->supported_rec_devices;
1046 return put_user(val, (int *)arg);
1047 break;
1049 case SOUND_MIXER_CAPS:
1050 val=SOUND_CAP_EXCL_INPUT;
1051 return put_user(val, (int *)arg);
1052 break;
1054 default:
1055 if ((val=ad1816_mixer_get (devc, cmd & 0xff))<0) {
1056 return val;
1057 } else {
1058 return put_user(val, (int *)arg);
1062 } else {
1063 /* not for mixer */
1064 return -(EINVAL);
1068 /* ------------------------------------------------------------------- */
1070 /* Mixer structure */
1072 static struct mixer_operations ad1816_mixer_operations =
1074 "AD1816",
1075 "AD1816 Mixer",
1076 ad1816_mixer_ioctl
1080 /* ------------------------------------------------------------------- */
1082 /* stuff for card recognition, init and unloading */
1085 /* replace with probe routine */
1086 int probe_ad1816 ( struct address_info *hw_config )
1088 ad1816_info *devc = &dev_info[nr_ad1816_devs];
1089 int io_base=hw_config->io_base;
1090 int *osp=hw_config->osp;
1091 int tmp;
1093 printk("ad1816: AD1816 sounddriver Copyright (C) 1998 by Thorsten Knabe\n");
1094 printk("ad1816: $Header: /home/tek/tmp/CVSROOT/sound21/ad1816.c,v 1.28 1999/01/16 19:01:36 tek Exp $\n");
1095 printk("ad1816: io=0x%x, irq=%d, dma=%d, dma2=%d, isadmabug=%d\n",
1096 hw_config->io_base,
1097 hw_config->irq,
1098 hw_config->dma,
1099 hw_config->dma2,
1100 isa_dma_bridge_buggy);
1102 if (check_region (io_base, 16)) {
1103 printk ("ad1816: I/O port 0x%03x not free\n", io_base);
1104 return 0;
1107 DEBUGLOG(printk ("ad1816: detect(%x)\n", io_base));
1109 if (nr_ad1816_devs >= MAX_AUDIO_DEV) {
1110 printk ("ad1816: detect error - step 0\n");
1111 return 0;
1114 devc->base = io_base;
1115 devc->irq_ok = 0;
1116 devc->irq = 0;
1117 devc->opened = 0;
1118 devc->osp = osp;
1120 /* base+0: bit 1 must be set but not 255 */
1121 tmp=inb(devc->base);
1122 if ( (tmp&0x80)==0 || tmp==255 ) {
1123 DEBUGLOG (printk ("ad1816: Chip is not an AD1816 or chip is not active (Test 0)\n"));
1124 return(0);
1128 /* writes to ireg 8 are copied to ireg 9 */
1129 ad_write(devc,8,12345);
1130 if (ad_read(devc,9)!=12345) {
1131 DEBUGLOG (printk ("ad1816: Chip is not an AD1816 (Test 1)\n"));
1132 return(0);
1135 /* writes to ireg 8 are copied to ireg 9 */
1136 ad_write(devc,8,54321);
1137 if (ad_read(devc,9)!=54321) {
1138 DEBUGLOG (printk ("ad1816: Chip is not an AD1816 (Test 2)\n"));
1139 return(0);
1142 /* writes to ireg 10 are copied to ireg 11 */
1143 ad_write(devc,10,54321);
1144 if (ad_read(devc,11)!=54321) {
1145 DEBUGLOG (printk ("ad1816: Chip is not an AD1816 (Test 3)\n"));
1146 return(0);
1149 /* writes to ireg 10 are copied to ireg 11 */
1150 ad_write(devc,10,12345);
1151 if (ad_read(devc,11)!=12345) {
1152 DEBUGLOG (printk ("ad1816: Chip is not an AD1816 (Test 4)\n"));
1153 return(0);
1156 /* bit in base +1 cannot be set to 1 */
1157 tmp=inb(devc->base+1);
1158 outb(0xff,devc->base+1);
1159 if (inb(devc->base+1)!=tmp) {
1160 DEBUGLOG (printk ("ad1816: Chip is not an AD1816 (Test 5)\n"));
1161 return(0);
1165 DEBUGLOG (printk ("ad1816: detect() - Detected OK\n"));
1166 DEBUGLOG (printk ("ad1816: AD1816 Version: %d\n",ad_read(devc,45)));
1168 /* detection was successful */
1169 return 1;
1173 /* allocate resources from the kernel. If any allocation fails, free
1174 all allocated resources and exit attach.
1178 void attach_ad1816 (struct address_info *hw_config)
1180 int my_dev;
1181 char dev_name[100];
1182 ad1816_info *devc = &dev_info[nr_ad1816_devs];
1185 /* allocate i/o ports */
1186 request_region (hw_config->io_base, 16, "AD1816 Sound");
1187 devc->base = hw_config->io_base;
1189 /* disable all interrupts */
1190 ad_write(devc,1,0);
1192 /* Clear pending interrupts */
1193 outb (0, devc->base+1);
1195 /* allocate irq */
1196 if (hw_config->irq < 0 || hw_config->irq > 15) {
1197 release_region(hw_config->io_base, 16);
1198 return;
1200 if (request_irq(hw_config->irq, ad1816_interrupt,0,
1201 "SoundPort",
1202 hw_config->osp) < 0) {
1203 printk ("ad1816: IRQ in use\n");
1204 release_region(hw_config->io_base, 16);
1205 return;
1207 devc->irq=hw_config->irq;
1209 /* DMA stuff */
1210 if (sound_alloc_dma (hw_config->dma, "Sound System")) {
1211 printk ("ad1816: Can't allocate DMA%d\n", hw_config->dma);
1212 free_irq(hw_config->irq,hw_config->osp);
1213 release_region(hw_config->io_base, 16);
1214 return;
1216 devc->dma_playback=hw_config->dma;
1218 if ( hw_config->dma2 != -1 && hw_config->dma2 != hw_config->dma) {
1219 if (sound_alloc_dma (hw_config->dma2, "Sound System (capture)")) {
1220 printk ("ad1816: Can't allocate DMA%d\n", hw_config->dma2);
1221 sound_free_dma(hw_config->dma);
1222 free_irq(hw_config->irq,hw_config->osp);
1223 release_region(hw_config->io_base, 16);
1224 return;
1226 devc->dma_capture=hw_config->dma2;
1227 devc->audio_mode=DMA_AUTOMODE|DMA_DUPLEX;
1228 } else {
1229 devc->dma_capture=-1;
1230 devc->audio_mode=DMA_AUTOMODE;
1233 sprintf (dev_name,"AD1816 audio driver");
1235 conf_printf2 (dev_name,
1236 devc->base, devc->irq, hw_config->dma, hw_config->dma2);
1238 /* register device */
1239 if ((my_dev = sound_install_audiodrv (AUDIO_DRIVER_VERSION,
1240 dev_name,
1241 &ad1816_audio_driver,
1242 sizeof (struct audio_driver),
1243 devc->audio_mode,
1244 ad_format_mask,
1245 devc,
1246 hw_config->dma,
1247 hw_config->dma2)) < 0) {
1248 printk ("ad1816: Can't install sound driver\n");
1249 if (devc->dma_capture>=0) {
1250 sound_free_dma(hw_config->dma2);
1252 sound_free_dma(hw_config->dma);
1253 free_irq(hw_config->irq,hw_config->osp);
1254 release_region(hw_config->io_base, 16);
1255 return;
1259 /* fill rest of structure with reasonable default values */
1260 irq2dev[hw_config->irq] = devc->dev_no = my_dev;
1261 devc->opened = 0;
1262 devc->irq_ok = 0;
1263 devc->osp = hw_config->osp;
1264 nr_ad1816_devs++;
1266 ad_write(devc,32,0x80f0); /* sound system mode */
1267 ad_write(devc,33,0x03f8); /* enable all audiosources for dsp */
1268 ad_write(devc,4,0x8080); /* default values for volumes (muted)*/
1269 ad_write(devc,5,0x8080);
1270 ad_write(devc,6,0x8080);
1271 ad_write(devc,7,0x8080);
1272 ad_write(devc,15,0x8888);
1273 ad_write(devc,16,0x8888);
1274 ad_write(devc,17,0x8888);
1275 ad_write(devc,18,0x8888);
1276 ad_write(devc,19,0xc888); /* +20db mic active */
1277 ad_write(devc,14,0x0000); /* Master volume unmuted full power */
1278 ad_write(devc,39,0x009f); /* 3D effect on 0% phone out muted */
1279 ad_write(devc,44,0x0080); /* everything on power, 3d enabled for d/a */
1280 outb(0x10,devc->base+8); /* set dma mode */
1281 outb(0x10,devc->base+9);
1283 /* enable capture + playback interrupt */
1284 ad_write(devc,1,0xc000);
1286 /* set mixer defaults */
1287 ad1816_mixer_reset (devc);
1289 /* register mixer */
1290 if ((audio_devs[my_dev]->mixer_dev=sound_install_mixer(
1291 MIXER_DRIVER_VERSION,
1292 dev_name,
1293 &ad1816_mixer_operations,
1294 sizeof (struct mixer_operations),
1295 devc)) >= 0) {
1296 audio_devs[my_dev]->min_fragment = 0;
1300 void unload_card(ad1816_info *devc)
1302 int mixer, dev = 0;
1304 if (devc != NULL) {
1305 DEBUGLOG (printk("ad1816: Unloading card at base=%x\n",devc->base));
1307 dev = devc->dev_no;
1308 mixer = audio_devs[dev]->mixer_dev;
1310 /* unreg mixer*/
1311 if(mixer>=0) {
1312 sound_unload_mixerdev(mixer);
1314 sound_unload_audiodev(dev);
1316 /* free dma channels */
1317 if (devc->dma_capture>=0) {
1318 sound_free_dma(devc->dma_capture);
1321 /* card wont get added if resources could not be allocated
1322 thus we need not ckeck if allocation was successful */
1323 sound_free_dma (devc->dma_playback);
1324 free_irq(devc->irq, devc->osp);
1325 release_region (devc->base, 16);
1327 DEBUGLOG (printk("ad1816: Unloading card at base=%x was successful\n",devc->base));
1329 } else {
1330 printk ("ad1816: no device/card specified\n");
1334 void unload_ad1816 (struct address_info *hw_config)
1336 int i;
1337 ad1816_info *devc = NULL;
1339 /* remove any soundcard */
1340 if (hw_config==NULL) {
1341 for (i = 0; i < nr_ad1816_devs; i++) {
1342 devc = &dev_info[i];
1343 unload_card(devc);
1345 nr_ad1816_devs=0;
1346 } else {
1347 /* remove specified soundcard */
1348 for (i = 0; i < nr_ad1816_devs; i++) {
1349 int j;
1351 if (dev_info[i].base == hw_config->io_base) {
1352 devc = &dev_info[i];
1353 unload_card(devc);
1354 nr_ad1816_devs--;
1355 for ( j=i; j < nr_ad1816_devs ; j++) {
1356 dev_info[j] = dev_info[j+1];
1358 i--;
1365 /* ----------------------------- 2.1.xxx module stuff ----------------- */
1367 EXPORT_SYMBOL(ad1816_interrupt);
1368 EXPORT_SYMBOL(probe_ad1816);
1369 EXPORT_SYMBOL(attach_ad1816);
1370 EXPORT_SYMBOL(unload_ad1816);
1373 #ifdef MODULE
1375 int io = -1;
1376 int irq = -1;
1377 int dma = -1;
1378 int dma2 = -1;
1380 MODULE_PARM(io,"i");
1381 MODULE_PARM(irq,"i");
1382 MODULE_PARM(dma,"i");
1383 MODULE_PARM(dma2,"i");
1384 MODULE_PARM(ad1816_clockfreq,"i");
1386 struct address_info cfg;
1389 int init_module(void)
1391 if (io == -1 || irq == -1 || dma == -1 || dma2 == -1) {
1392 printk("ad1816: dma, dma2, irq and io must be set.\n");
1393 return -EINVAL;
1395 cfg.io_base = io;
1396 cfg.irq = irq;
1397 cfg.dma = dma;
1398 cfg.dma2 = dma2;
1400 if (probe_ad1816(&cfg) == 0) {
1401 return -ENODEV;
1403 attach_ad1816(&cfg);
1404 SOUND_LOCK;
1405 return 0;
1409 void cleanup_module(void)
1411 unload_ad1816(NULL);
1412 SOUND_LOCK_END;
1415 #endif /* MODULE */
1417 #endif /* CONFIG_AD1816 */