aboutsummaryrefslogtreecommitdiffstats
path: root/sound/oss/ad1816.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /sound/oss/ad1816.c
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'sound/oss/ad1816.c')
-rw-r--r--sound/oss/ad1816.c1369
1 files changed, 1369 insertions, 0 deletions
diff --git a/sound/oss/ad1816.c b/sound/oss/ad1816.c
new file mode 100644
index 000000000000..22dae5d0fda3
--- /dev/null
+++ b/sound/oss/ad1816.c
@@ -0,0 +1,1369 @@
1/*
2 *
3 * AD1816 lowlevel sound driver for Linux 2.6.0 and above
4 *
5 * Copyright (C) 1998-2003 by Thorsten Knabe <linux@thorsten-knabe.de>
6 *
7 * Based on the CS4232/AD1848 driver Copyright (C) by Hannu Savolainen 1993-1996
8 *
9 *
10 * version: 1.5
11 * status: beta
12 * date: 2003/07/15
13 *
14 * Changes:
15 * Oleg Drokin: Some cleanup of load/unload functions. 1998/11/24
16 *
17 * Thorsten Knabe: attach and unload rewritten,
18 * some argument checks added 1998/11/30
19 *
20 * Thorsten Knabe: Buggy isa bridge workaround added 1999/01/16
21 *
22 * David Moews/Thorsten Knabe: Introduced options
23 * parameter. Added slightly modified patch from
24 * David Moews to disable dsp audio sources by setting
25 * bit 0 of options parameter. This seems to be
26 * required by some Aztech/Newcom SC-16 cards. 1999/04/18
27 *
28 * Christoph Hellwig: Adapted to module_init/module_exit. 2000/03/03
29 *
30 * Christoph Hellwig: Added isapnp support 2000/03/15
31 *
32 * Arnaldo Carvalho de Melo: get rid of check_region 2001/10/07
33 *
34 * Thorsten Knabe: Compiling with CONFIG_PNP enabled
35 * works again. It is now possible to use more than one
36 * AD1816 sound card. Sample rate now may be changed during
37 * playback/capture. printk() uses log levels everywhere.
38 * SMP fixes. DMA handling fixes.
39 * Other minor code cleanup. 2003/07/15
40 *
41 */
42
43
44#include <linux/config.h>
45#include <linux/module.h>
46#include <linux/init.h>
47#include <linux/interrupt.h>
48#include <linux/isapnp.h>
49#include <linux/stddef.h>
50#include <linux/spinlock.h>
51#include "sound_config.h"
52
53#define DEBUGNOISE(x)
54
55#define CHECK_FOR_POWER { int timeout=100; \
56 while (timeout > 0 && (inb(devc->base)&0x80)!= 0x80) {\
57 timeout--; \
58 } \
59 if (timeout==0) {\
60 printk(KERN_WARNING "ad1816: Check for power failed in %s line: %d\n",__FILE__,__LINE__); \
61 } \
62}
63
64/* structure to hold device specific information */
65typedef struct
66{
67 int base; /* set in attach */
68 int irq;
69 int dma_playback;
70 int dma_capture;
71
72 int opened; /* open */
73 int speed;
74 int channels;
75 int audio_format;
76 int audio_mode;
77
78 int recmask; /* setup */
79 unsigned char format_bits;
80 int supported_devices;
81 int supported_rec_devices;
82 unsigned short levels[SOUND_MIXER_NRDEVICES];
83 /* misc */
84 struct pnp_dev *pnpdev; /* configured via pnp */
85 int dev_no; /* this is the # in audio_devs and NOT
86 in ad1816_info */
87 spinlock_t lock;
88} ad1816_info;
89
90static int nr_ad1816_devs;
91static int ad1816_clockfreq = 33000;
92static int options;
93
94/* supported audio formats */
95static int ad_format_mask =
96AFMT_U8 | AFMT_S16_LE | AFMT_S16_BE | AFMT_MU_LAW | AFMT_A_LAW;
97
98/* array of device info structures */
99static ad1816_info dev_info[MAX_AUDIO_DEV];
100
101
102/* ------------------------------------------------------------------- */
103
104/* functions for easier access to inderect registers */
105
106static int ad_read (ad1816_info * devc, int reg)
107{
108 int result;
109
110 CHECK_FOR_POWER;
111 outb ((unsigned char) (reg & 0x3f), devc->base+0);
112 result = inb(devc->base+2);
113 result+= inb(devc->base+3)<<8;
114 return (result);
115}
116
117
118static void ad_write (ad1816_info * devc, int reg, int data)
119{
120 CHECK_FOR_POWER;
121 outb ((unsigned char) (reg & 0xff), devc->base+0);
122 outb ((unsigned char) (data & 0xff),devc->base+2);
123 outb ((unsigned char) ((data>>8)&0xff),devc->base+3);
124}
125
126/* ------------------------------------------------------------------- */
127
128/* function interface required by struct audio_driver */
129
130static void ad1816_halt_input (int dev)
131{
132 unsigned long flags;
133 ad1816_info *devc = (ad1816_info *) audio_devs[dev]->devc;
134 unsigned char buffer;
135
136 DEBUGNOISE(printk(KERN_DEBUG "ad1816: halt_input called\n"));
137
138 spin_lock_irqsave(&devc->lock,flags);
139
140 if(!isa_dma_bridge_buggy) {
141 disable_dma(audio_devs[dev]->dmap_in->dma);
142 }
143
144 buffer=inb(devc->base+9);
145 if (buffer & 0x01) {
146 /* disable capture */
147 outb(buffer & ~0x01,devc->base+9);
148 }
149
150 if(!isa_dma_bridge_buggy) {
151 enable_dma(audio_devs[dev]->dmap_in->dma);
152 }
153
154 /* Clear interrupt status */
155 outb (~0x40, devc->base+1);
156
157 devc->audio_mode &= ~PCM_ENABLE_INPUT;
158 spin_unlock_irqrestore(&devc->lock,flags);
159}
160
161static void ad1816_halt_output (int dev)
162{
163 unsigned long flags;
164 ad1816_info *devc = (ad1816_info *) audio_devs[dev]->devc;
165
166 unsigned char buffer;
167
168 DEBUGNOISE(printk(KERN_DEBUG "ad1816: halt_output called!\n"));
169
170 spin_lock_irqsave(&devc->lock,flags);
171 /* Mute pcm output */
172 ad_write(devc, 4, ad_read(devc,4)|0x8080);
173
174 if(!isa_dma_bridge_buggy) {
175 disable_dma(audio_devs[dev]->dmap_out->dma);
176 }
177
178 buffer=inb(devc->base+8);
179 if (buffer & 0x01) {
180 /* disable capture */
181 outb(buffer & ~0x01,devc->base+8);
182 }
183
184 if(!isa_dma_bridge_buggy) {
185 enable_dma(audio_devs[dev]->dmap_out->dma);
186 }
187
188 /* Clear interrupt status */
189 outb ((unsigned char)~0x80, devc->base+1);
190
191 devc->audio_mode &= ~PCM_ENABLE_OUTPUT;
192 spin_unlock_irqrestore(&devc->lock,flags);
193}
194
195static void ad1816_output_block (int dev, unsigned long buf,
196 int count, int intrflag)
197{
198 unsigned long flags;
199 unsigned long cnt;
200 ad1816_info *devc = (ad1816_info *) audio_devs[dev]->devc;
201
202 DEBUGNOISE(printk(KERN_DEBUG "ad1816: output_block called buf=%ld count=%d flags=%d\n",buf,count,intrflag));
203
204 cnt = count/4 - 1;
205
206 spin_lock_irqsave(&devc->lock,flags);
207
208 /* set transfer count */
209 ad_write (devc, 8, cnt & 0xffff);
210
211 devc->audio_mode |= PCM_ENABLE_OUTPUT;
212 spin_unlock_irqrestore(&devc->lock,flags);
213}
214
215
216static void ad1816_start_input (int dev, unsigned long buf, int count,
217 int intrflag)
218{
219 unsigned long flags;
220 unsigned long cnt;
221 ad1816_info *devc = (ad1816_info *) audio_devs[dev]->devc;
222
223 DEBUGNOISE(printk(KERN_DEBUG "ad1816: start_input called buf=%ld count=%d flags=%d\n",buf,count,intrflag));
224
225 cnt = count/4 - 1;
226
227 spin_lock_irqsave(&devc->lock,flags);
228
229 /* set transfer count */
230 ad_write (devc, 10, cnt & 0xffff);
231 devc->audio_mode |= PCM_ENABLE_INPUT;
232 spin_unlock_irqrestore(&devc->lock,flags);
233}
234
235static int ad1816_prepare_for_input (int dev, int bsize, int bcount)
236{
237 unsigned long flags;
238 unsigned int freq;
239 ad1816_info *devc = (ad1816_info *) audio_devs[dev]->devc;
240 unsigned char fmt_bits;
241
242 DEBUGNOISE(printk(KERN_DEBUG "ad1816: prepare_for_input called: bsize=%d bcount=%d\n",bsize,bcount));
243
244 spin_lock_irqsave(&devc->lock,flags);
245 fmt_bits= (devc->format_bits&0x7)<<3;
246
247 /* set mono/stereo mode */
248 if (devc->channels > 1) {
249 fmt_bits |=0x4;
250 }
251 /* set Mono/Stereo in playback/capture register */
252 outb( (inb(devc->base+8) & ~0x3C)|fmt_bits, devc->base+8);
253 outb( (inb(devc->base+9) & ~0x3C)|fmt_bits, devc->base+9);
254
255 freq=((unsigned int)devc->speed*33000)/ad1816_clockfreq;
256
257 /* write playback/capture speeds */
258 ad_write (devc, 2, freq & 0xffff);
259 ad_write (devc, 3, freq & 0xffff);
260
261 spin_unlock_irqrestore(&devc->lock,flags);
262
263 ad1816_halt_input(dev);
264 return 0;
265}
266
267static int ad1816_prepare_for_output (int dev, int bsize, int bcount)
268{
269 unsigned long flags;
270 unsigned int freq;
271 ad1816_info *devc = (ad1816_info *) audio_devs[dev]->devc;
272 unsigned char fmt_bits;
273
274 DEBUGNOISE(printk(KERN_DEBUG "ad1816: prepare_for_output called: bsize=%d bcount=%d\n",bsize,bcount));
275
276 spin_lock_irqsave(&devc->lock,flags);
277
278 fmt_bits= (devc->format_bits&0x7)<<3;
279 /* set mono/stereo mode */
280 if (devc->channels > 1) {
281 fmt_bits |=0x4;
282 }
283
284 /* write format bits to playback/capture registers */
285 outb( (inb(devc->base+8) & ~0x3C)|fmt_bits, devc->base+8);
286 outb( (inb(devc->base+9) & ~0x3C)|fmt_bits, devc->base+9);
287
288 freq=((unsigned int)devc->speed*33000)/ad1816_clockfreq;
289
290 /* write playback/capture speeds */
291 ad_write (devc, 2, freq & 0xffff);
292 ad_write (devc, 3, freq & 0xffff);
293
294 spin_unlock_irqrestore(&devc->lock,flags);
295
296 ad1816_halt_output(dev);
297 return 0;
298
299}
300
301static void ad1816_trigger (int dev, int state)
302{
303 unsigned long flags;
304 ad1816_info *devc = (ad1816_info *) audio_devs[dev]->devc;
305
306 DEBUGNOISE(printk(KERN_DEBUG "ad1816: trigger called! (devc=%d,devc->base=%d\n", devc, devc->base));
307
308 /* mode may have changed */
309
310 spin_lock_irqsave(&devc->lock,flags);
311
312 /* mask out modes not specified on open call */
313 state &= devc->audio_mode;
314
315 /* setup soundchip to new io-mode */
316 if (state & PCM_ENABLE_INPUT) {
317 /* enable capture */
318 outb(inb(devc->base+9)|0x01, devc->base+9);
319 } else {
320 /* disable capture */
321 outb(inb(devc->base+9)&~0x01, devc->base+9);
322 }
323
324 if (state & PCM_ENABLE_OUTPUT) {
325 /* enable playback */
326 outb(inb(devc->base+8)|0x01, devc->base+8);
327 /* unmute pcm output */
328 ad_write(devc, 4, ad_read(devc,4)&~0x8080);
329 } else {
330 /* mute pcm output */
331 ad_write(devc, 4, ad_read(devc,4)|0x8080);
332 /* disable capture */
333 outb(inb(devc->base+8)&~0x01, devc->base+8);
334 }
335 spin_unlock_irqrestore(&devc->lock,flags);
336}
337
338
339/* halt input & output */
340static void ad1816_halt (int dev)
341{
342 ad1816_halt_input(dev);
343 ad1816_halt_output(dev);
344}
345
346static void ad1816_reset (int dev)
347{
348 ad1816_halt (dev);
349}
350
351/* set playback speed */
352static int ad1816_set_speed (int dev, int arg)
353{
354 unsigned long flags;
355 unsigned int freq;
356 int ret;
357
358 ad1816_info *devc = (ad1816_info *) audio_devs[dev]->devc;
359
360 spin_lock_irqsave(&devc->lock, flags);
361 if (arg == 0) {
362 ret = devc->speed;
363 spin_unlock_irqrestore(&devc->lock, flags);
364 return ret;
365 }
366 /* range checking */
367 if (arg < 4000) {
368 arg = 4000;
369 }
370 if (arg > 55000) {
371 arg = 55000;
372 }
373 devc->speed = arg;
374
375 /* change speed during playback */
376 freq=((unsigned int)devc->speed*33000)/ad1816_clockfreq;
377 /* write playback/capture speeds */
378 ad_write (devc, 2, freq & 0xffff);
379 ad_write (devc, 3, freq & 0xffff);
380
381 ret = devc->speed;
382 spin_unlock_irqrestore(&devc->lock, flags);
383 return ret;
384
385}
386
387static unsigned int ad1816_set_bits (int dev, unsigned int arg)
388{
389 unsigned long flags;
390 ad1816_info *devc = (ad1816_info *) audio_devs[dev]->devc;
391
392 static struct format_tbl {
393 int format;
394 unsigned char bits;
395 } format2bits[] = {
396 { 0, 0 },
397 { AFMT_MU_LAW, 1 },
398 { AFMT_A_LAW, 3 },
399 { AFMT_IMA_ADPCM, 0 },
400 { AFMT_U8, 0 },
401 { AFMT_S16_LE, 2 },
402 { AFMT_S16_BE, 6 },
403 { AFMT_S8, 0 },
404 { AFMT_U16_LE, 0 },
405 { AFMT_U16_BE, 0 }
406 };
407
408 int i, n = sizeof (format2bits) / sizeof (struct format_tbl);
409
410 spin_lock_irqsave(&devc->lock, flags);
411 /* return current format */
412 if (arg == 0) {
413 arg = devc->audio_format;
414 spin_unlock_irqrestore(&devc->lock, flags);
415 return arg;
416 }
417 devc->audio_format = arg;
418
419 /* search matching format bits */
420 for (i = 0; i < n; i++)
421 if (format2bits[i].format == arg) {
422 devc->format_bits = format2bits[i].bits;
423 devc->audio_format = arg;
424 spin_unlock_irqrestore(&devc->lock, flags);
425 return arg;
426 }
427
428 /* Still hanging here. Something must be terribly wrong */
429 devc->format_bits = 0;
430 devc->audio_format = AFMT_U8;
431 spin_unlock_irqrestore(&devc->lock, flags);
432 return(AFMT_U8);
433}
434
435static short ad1816_set_channels (int dev, short arg)
436{
437 ad1816_info *devc = (ad1816_info *) audio_devs[dev]->devc;
438
439 if (arg != 1 && arg != 2)
440 return devc->channels;
441
442 devc->channels = arg;
443 return arg;
444}
445
446/* open device */
447static int ad1816_open (int dev, int mode)
448{
449 ad1816_info *devc = NULL;
450 unsigned long flags;
451
452 /* is device number valid ? */
453 if (dev < 0 || dev >= num_audiodevs)
454 return -(ENXIO);
455
456 /* get device info of this dev */
457 devc = (ad1816_info *) audio_devs[dev]->devc;
458
459 /* make check if device already open atomic */
460 spin_lock_irqsave(&devc->lock,flags);
461
462 if (devc->opened) {
463 spin_unlock_irqrestore(&devc->lock,flags);
464 return -(EBUSY);
465 }
466
467 /* mark device as open */
468 devc->opened = 1;
469
470 devc->audio_mode = 0;
471 devc->speed = 8000;
472 devc->audio_format=AFMT_U8;
473 devc->channels=1;
474 spin_unlock_irqrestore(&devc->lock,flags);
475 ad1816_reset(devc->dev_no); /* halt all pending output */
476 return 0;
477}
478
479static void ad1816_close (int dev) /* close device */
480{
481 unsigned long flags;
482 ad1816_info *devc = (ad1816_info *) audio_devs[dev]->devc;
483
484 /* halt all pending output */
485 ad1816_reset(devc->dev_no);
486
487 spin_lock_irqsave(&devc->lock,flags);
488 devc->opened = 0;
489 devc->audio_mode = 0;
490 devc->speed = 8000;
491 devc->audio_format=AFMT_U8;
492 devc->format_bits = 0;
493 spin_unlock_irqrestore(&devc->lock,flags);
494}
495
496
497/* ------------------------------------------------------------------- */
498
499/* Audio driver structure */
500
501static struct audio_driver ad1816_audio_driver =
502{
503 .owner = THIS_MODULE,
504 .open = ad1816_open,
505 .close = ad1816_close,
506 .output_block = ad1816_output_block,
507 .start_input = ad1816_start_input,
508 .prepare_for_input = ad1816_prepare_for_input,
509 .prepare_for_output = ad1816_prepare_for_output,
510 .halt_io = ad1816_halt,
511 .halt_input = ad1816_halt_input,
512 .halt_output = ad1816_halt_output,
513 .trigger = ad1816_trigger,
514 .set_speed = ad1816_set_speed,
515 .set_bits = ad1816_set_bits,
516 .set_channels = ad1816_set_channels,
517};
518
519
520/* ------------------------------------------------------------------- */
521
522/* Interrupt handler */
523
524
525static irqreturn_t ad1816_interrupt (int irq, void *dev_id, struct pt_regs *dummy)
526{
527 unsigned char status;
528 ad1816_info *devc = (ad1816_info *)dev_id;
529
530 if (irq < 0 || irq > 15) {
531 printk(KERN_WARNING "ad1816: Got bogus interrupt %d\n", irq);
532 return IRQ_NONE;
533 }
534
535 spin_lock(&devc->lock);
536
537 /* read interrupt register */
538 status = inb (devc->base+1);
539 /* Clear all interrupt */
540 outb (~status, devc->base+1);
541
542 DEBUGNOISE(printk(KERN_DEBUG "ad1816: Got interrupt subclass %d\n",status));
543
544 if (status == 0) {
545 DEBUGNOISE(printk(KERN_DEBUG "ad1816: interrupt: Got interrupt, but no source.\n"));
546 spin_unlock(&devc->lock);
547 return IRQ_NONE;
548 }
549
550 if (devc->opened && (devc->audio_mode & PCM_ENABLE_INPUT) && (status&64))
551 DMAbuf_inputintr (devc->dev_no);
552
553 if (devc->opened && (devc->audio_mode & PCM_ENABLE_OUTPUT) && (status & 128))
554 DMAbuf_outputintr (devc->dev_no, 1);
555
556 spin_unlock(&devc->lock);
557 return IRQ_HANDLED;
558}
559
560/* ------------------------------------------------------------------- */
561
562/* Mixer stuff */
563
564struct mixer_def {
565 unsigned int regno: 7;
566 unsigned int polarity:1; /* 0=normal, 1=reversed */
567 unsigned int bitpos:4;
568 unsigned int nbits:4;
569};
570
571static char mix_cvt[101] = {
572 0, 0, 3, 7,10,13,16,19,21,23,26,28,30,32,34,35,37,39,40,42,
573 43,45,46,47,49,50,51,52,53,55,56,57,58,59,60,61,62,63,64,65,
574 65,66,67,68,69,70,70,71,72,73,73,74,75,75,76,77,77,78,79,79,
575 80,81,81,82,82,83,84,84,85,85,86,86,87,87,88,88,89,89,90,90,
576 91,91,92,92,93,93,94,94,95,95,96,96,96,97,97,98,98,98,99,99,
577 100
578};
579
580typedef struct mixer_def mixer_ent;
581
582/*
583 * Most of the mixer entries work in backwards. Setting the polarity field
584 * makes them to work correctly.
585 *
586 * The channel numbering used by individual soundcards is not fixed. Some
587 * cards have assigned different meanings for the AUX1, AUX2 and LINE inputs.
588 * The current version doesn't try to compensate this.
589 */
590
591#define MIX_ENT(name, reg_l, pola_l, pos_l, len_l, reg_r, pola_r, pos_r, len_r) \
592 {{reg_l, pola_l, pos_l, len_l}, {reg_r, pola_r, pos_r, len_r}}
593
594
595mixer_ent mix_devices[SOUND_MIXER_NRDEVICES][2] = {
596MIX_ENT(SOUND_MIXER_VOLUME, 14, 1, 8, 5, 14, 1, 0, 5),
597MIX_ENT(SOUND_MIXER_BASS, 0, 0, 0, 0, 0, 0, 0, 0),
598MIX_ENT(SOUND_MIXER_TREBLE, 0, 0, 0, 0, 0, 0, 0, 0),
599MIX_ENT(SOUND_MIXER_SYNTH, 5, 1, 8, 6, 5, 1, 0, 6),
600MIX_ENT(SOUND_MIXER_PCM, 4, 1, 8, 6, 4, 1, 0, 6),
601MIX_ENT(SOUND_MIXER_SPEAKER, 0, 0, 0, 0, 0, 0, 0, 0),
602MIX_ENT(SOUND_MIXER_LINE, 18, 1, 8, 5, 18, 1, 0, 5),
603MIX_ENT(SOUND_MIXER_MIC, 19, 1, 8, 5, 19, 1, 0, 5),
604MIX_ENT(SOUND_MIXER_CD, 15, 1, 8, 5, 15, 1, 0, 5),
605MIX_ENT(SOUND_MIXER_IMIX, 0, 0, 0, 0, 0, 0, 0, 0),
606MIX_ENT(SOUND_MIXER_ALTPCM, 0, 0, 0, 0, 0, 0, 0, 0),
607MIX_ENT(SOUND_MIXER_RECLEV, 20, 0, 8, 4, 20, 0, 0, 4),
608MIX_ENT(SOUND_MIXER_IGAIN, 0, 0, 0, 0, 0, 0, 0, 0),
609MIX_ENT(SOUND_MIXER_OGAIN, 0, 0, 0, 0, 0, 0, 0, 0),
610MIX_ENT(SOUND_MIXER_LINE1, 17, 1, 8, 5, 17, 1, 0, 5),
611MIX_ENT(SOUND_MIXER_LINE2, 16, 1, 8, 5, 16, 1, 0, 5),
612MIX_ENT(SOUND_MIXER_LINE3, 39, 0, 9, 4, 39, 1, 0, 5)
613};
614
615
616static unsigned short default_mixer_levels[SOUND_MIXER_NRDEVICES] =
617{
618 0x4343, /* Master Volume */
619 0x3232, /* Bass */
620 0x3232, /* Treble */
621 0x0000, /* FM */
622 0x4343, /* PCM */
623 0x0000, /* PC Speaker */
624 0x0000, /* Ext Line */
625 0x0000, /* Mic */
626 0x0000, /* CD */
627 0x0000, /* Recording monitor */
628 0x0000, /* SB PCM */
629 0x0000, /* Recording level */
630 0x0000, /* Input gain */
631 0x0000, /* Output gain */
632 0x0000, /* Line1 */
633 0x0000, /* Line2 */
634 0x0000 /* Line3 (usually line in)*/
635};
636
637#define LEFT_CHN 0
638#define RIGHT_CHN 1
639
640
641
642static int
643ad1816_set_recmask (ad1816_info * devc, int mask)
644{
645 unsigned long flags;
646 unsigned char recdev;
647 int i, n;
648
649 spin_lock_irqsave(&devc->lock, flags);
650 mask &= devc->supported_rec_devices;
651
652 n = 0;
653 /* Count selected device bits */
654 for (i = 0; i < 32; i++)
655 if (mask & (1 << i))
656 n++;
657
658 if (n == 0)
659 mask = SOUND_MASK_MIC;
660 else if (n != 1) { /* Too many devices selected */
661 /* Filter out active settings */
662 mask &= ~devc->recmask;
663
664 n = 0;
665 /* Count selected device bits */
666 for (i = 0; i < 32; i++)
667 if (mask & (1 << i))
668 n++;
669
670 if (n != 1)
671 mask = SOUND_MASK_MIC;
672 }
673
674 switch (mask) {
675 case SOUND_MASK_MIC:
676 recdev = 5;
677 break;
678
679 case SOUND_MASK_LINE:
680 recdev = 0;
681 break;
682
683 case SOUND_MASK_CD:
684 recdev = 2;
685 break;
686
687 case SOUND_MASK_LINE1:
688 recdev = 4;
689 break;
690
691 case SOUND_MASK_LINE2:
692 recdev = 3;
693 break;
694
695 case SOUND_MASK_VOLUME:
696 recdev = 1;
697 break;
698
699 default:
700 mask = SOUND_MASK_MIC;
701 recdev = 5;
702 }
703
704 recdev <<= 4;
705 ad_write (devc, 20,
706 (ad_read (devc, 20) & 0x8f8f) | recdev | (recdev<<8));
707
708 devc->recmask = mask;
709 spin_unlock_irqrestore(&devc->lock, flags);
710 return mask;
711}
712
713static void
714change_bits (int *regval, int dev, int chn, int newval)
715{
716 unsigned char mask;
717 int shift;
718
719 /* Reverse polarity*/
720
721 if (mix_devices[dev][chn].polarity == 1)
722 newval = 100 - newval;
723
724 mask = (1 << mix_devices[dev][chn].nbits) - 1;
725 shift = mix_devices[dev][chn].bitpos;
726 /* Scale it */
727 newval = (int) ((newval * mask) + 50) / 100;
728 /* Clear bits */
729 *regval &= ~(mask << shift);
730 /* Set new value */
731 *regval |= (newval & mask) << shift;
732}
733
734static int
735ad1816_mixer_get (ad1816_info * devc, int dev)
736{
737 DEBUGNOISE(printk(KERN_DEBUG "ad1816: mixer_get called!\n"));
738
739 /* range check + supported mixer check */
740 if (dev < 0 || dev >= SOUND_MIXER_NRDEVICES )
741 return (-(EINVAL));
742 if (!((1 << dev) & devc->supported_devices))
743 return -(EINVAL);
744
745 return devc->levels[dev];
746}
747
748static int
749ad1816_mixer_set (ad1816_info * devc, int dev, int value)
750{
751 int left = value & 0x000000ff;
752 int right = (value & 0x0000ff00) >> 8;
753 int retvol;
754
755 int regoffs;
756 int val;
757 int valmute;
758 unsigned long flags;
759
760 DEBUGNOISE(printk(KERN_DEBUG "ad1816: mixer_set called!\n"));
761
762 if (dev < 0 || dev >= SOUND_MIXER_NRDEVICES )
763 return -(EINVAL);
764
765 if (left > 100)
766 left = 100;
767 if (left < 0)
768 left = 0;
769 if (right > 100)
770 right = 100;
771 if (right < 0)
772 right = 0;
773
774 /* Mono control */
775 if (mix_devices[dev][RIGHT_CHN].nbits == 0)
776 right = left;
777 retvol = left | (right << 8);
778
779 /* Scale it */
780
781 left = mix_cvt[left];
782 right = mix_cvt[right];
783
784 /* reject all mixers that are not supported */
785 if (!(devc->supported_devices & (1 << dev)))
786 return -(EINVAL);
787
788 /* sanity check */
789 if (mix_devices[dev][LEFT_CHN].nbits == 0)
790 return -(EINVAL);
791 spin_lock_irqsave(&devc->lock, flags);
792
793 /* keep precise volume internal */
794 devc->levels[dev] = retvol;
795
796 /* Set the left channel */
797 regoffs = mix_devices[dev][LEFT_CHN].regno;
798 val = ad_read (devc, regoffs);
799 change_bits (&val, dev, LEFT_CHN, left);
800
801 valmute=val;
802
803 /* Mute bit masking on some registers */
804 if ( regoffs==5 || regoffs==14 || regoffs==15 ||
805 regoffs==16 || regoffs==17 || regoffs==18 ||
806 regoffs==19 || regoffs==39) {
807 if (left==0)
808 valmute |= 0x8000;
809 else
810 valmute &= ~0x8000;
811 }
812 ad_write (devc, regoffs, valmute); /* mute */
813
814 /*
815 * Set the right channel
816 */
817
818 /* Was just a mono channel */
819 if (mix_devices[dev][RIGHT_CHN].nbits == 0) {
820 spin_unlock_irqrestore(&devc->lock, flags);
821 return retvol;
822 }
823
824 regoffs = mix_devices[dev][RIGHT_CHN].regno;
825 val = ad_read (devc, regoffs);
826 change_bits (&val, dev, RIGHT_CHN, right);
827
828 valmute=val;
829 if ( regoffs==5 || regoffs==14 || regoffs==15 ||
830 regoffs==16 || regoffs==17 || regoffs==18 ||
831 regoffs==19 || regoffs==39) {
832 if (right==0)
833 valmute |= 0x80;
834 else
835 valmute &= ~0x80;
836 }
837 ad_write (devc, regoffs, valmute); /* mute */
838 spin_unlock_irqrestore(&devc->lock, flags);
839 return retvol;
840}
841
842#define MIXER_DEVICES ( SOUND_MASK_VOLUME | \
843 SOUND_MASK_SYNTH | \
844 SOUND_MASK_PCM | \
845 SOUND_MASK_LINE | \
846 SOUND_MASK_LINE1 | \
847 SOUND_MASK_LINE2 | \
848 SOUND_MASK_LINE3 | \
849 SOUND_MASK_MIC | \
850 SOUND_MASK_CD | \
851 SOUND_MASK_RECLEV \
852 )
853#define REC_DEVICES ( SOUND_MASK_LINE2 |\
854 SOUND_MASK_LINE |\
855 SOUND_MASK_LINE1 |\
856 SOUND_MASK_MIC |\
857 SOUND_MASK_CD |\
858 SOUND_MASK_VOLUME \
859 )
860
861static void
862ad1816_mixer_reset (ad1816_info * devc)
863{
864 int i;
865
866 devc->supported_devices = MIXER_DEVICES;
867
868 devc->supported_rec_devices = REC_DEVICES;
869
870 for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
871 if (devc->supported_devices & (1 << i))
872 ad1816_mixer_set (devc, i, default_mixer_levels[i]);
873 ad1816_set_recmask (devc, SOUND_MASK_MIC);
874}
875
876static int
877ad1816_mixer_ioctl (int dev, unsigned int cmd, void __user * arg)
878{
879 ad1816_info *devc = mixer_devs[dev]->devc;
880 int val;
881 int __user *p = arg;
882
883 DEBUGNOISE(printk(KERN_DEBUG "ad1816: mixer_ioctl called!\n"));
884
885 /* Mixer ioctl */
886 if (((cmd >> 8) & 0xff) == 'M') {
887
888 /* set ioctl */
889 if (_SIOC_DIR (cmd) & _SIOC_WRITE) {
890 switch (cmd & 0xff){
891 case SOUND_MIXER_RECSRC:
892
893 if (get_user(val, p))
894 return -EFAULT;
895 val=ad1816_set_recmask (devc, val);
896 return put_user(val, p);
897 break;
898
899 default:
900 if (get_user(val, p))
901 return -EFAULT;
902 if ((val=ad1816_mixer_set (devc, cmd & 0xff, val))<0)
903 return val;
904 else
905 return put_user(val, p);
906 }
907 } else {
908 /* read ioctl */
909 switch (cmd & 0xff) {
910
911 case SOUND_MIXER_RECSRC:
912 val=devc->recmask;
913 return put_user(val, p);
914 break;
915
916 case SOUND_MIXER_DEVMASK:
917 val=devc->supported_devices;
918 return put_user(val, p);
919 break;
920
921 case SOUND_MIXER_STEREODEVS:
922 val=devc->supported_devices & ~(SOUND_MASK_SPEAKER | SOUND_MASK_IMIX);
923 return put_user(val, p);
924 break;
925
926 case SOUND_MIXER_RECMASK:
927 val=devc->supported_rec_devices;
928 return put_user(val, p);
929 break;
930
931 case SOUND_MIXER_CAPS:
932 val=SOUND_CAP_EXCL_INPUT;
933 return put_user(val, p);
934 break;
935
936 default:
937 if ((val=ad1816_mixer_get (devc, cmd & 0xff))<0)
938 return val;
939 else
940 return put_user(val, p);
941 }
942 }
943 } else
944 /* not for mixer */
945 return -(EINVAL);
946}
947
948/* ------------------------------------------------------------------- */
949
950/* Mixer structure */
951
952static struct mixer_operations ad1816_mixer_operations = {
953 .owner = THIS_MODULE,
954 .id = "AD1816",
955 .name = "AD1816 Mixer",
956 .ioctl = ad1816_mixer_ioctl
957};
958
959
960/* ------------------------------------------------------------------- */
961
962/* stuff for card recognition, init and unloading PNP ...*/
963
964
965/* check if AD1816 present at specified hw_config and register device with OS
966 * return 1 if initialization was successful, 0 otherwise
967 */
968static int __init ad1816_init_card (struct address_info *hw_config,
969 struct pnp_dev *pnp)
970{
971 ad1816_info *devc = NULL;
972 int tmp;
973 int oss_devno = -1;
974
975 printk(KERN_INFO "ad1816: initializing card: io=0x%x, irq=%d, dma=%d, "
976 "dma2=%d, clockfreq=%d, options=%d isadmabug=%d "
977 "%s\n",
978 hw_config->io_base,
979 hw_config->irq,
980 hw_config->dma,
981 hw_config->dma2,
982 ad1816_clockfreq,
983 options,
984 isa_dma_bridge_buggy,
985 pnp?"(PNP)":"");
986
987 /* ad1816_info structure remaining ? */
988 if (nr_ad1816_devs >= MAX_AUDIO_DEV) {
989 printk(KERN_WARNING "ad1816: no more ad1816_info structures "
990 "left\n");
991 goto out;
992 }
993
994 devc = &dev_info[nr_ad1816_devs];
995 devc->base = hw_config->io_base;
996 devc->irq = hw_config->irq;
997 devc->dma_playback=hw_config->dma;
998 devc->dma_capture=hw_config->dma2;
999 devc->opened = 0;
1000 devc->pnpdev = pnp;
1001 spin_lock_init(&devc->lock);
1002
1003 if (!request_region(devc->base, 16, "AD1816 Sound")) {
1004 printk(KERN_WARNING "ad1816: I/O port 0x%03x not free\n",
1005 devc->base);
1006 goto out;
1007 }
1008
1009 printk(KERN_INFO "ad1816: Examining AD1816 at address 0x%03x.\n",
1010 devc->base);
1011
1012
1013 /* tests for ad1816 */
1014 /* base+0: bit 1 must be set but not 255 */
1015 tmp=inb(devc->base);
1016 if ( (tmp&0x80)==0 || tmp==255 ) {
1017 printk (KERN_INFO "ad1816: Chip is not an AD1816 or chip "
1018 "is not active (Test 0)\n");
1019 goto out_release_region;
1020 }
1021
1022 /* writes to ireg 8 are copied to ireg 9 */
1023 ad_write(devc,8,12345);
1024 if (ad_read(devc,9)!=12345) {
1025 printk(KERN_INFO "ad1816: Chip is not an AD1816 (Test 1)\n");
1026 goto out_release_region;
1027 }
1028
1029 /* writes to ireg 8 are copied to ireg 9 */
1030 ad_write(devc,8,54321);
1031 if (ad_read(devc,9)!=54321) {
1032 printk(KERN_INFO "ad1816: Chip is not an AD1816 (Test 2)\n");
1033 goto out_release_region;
1034 }
1035
1036 /* writes to ireg 10 are copied to ireg 11 */
1037 ad_write(devc,10,54321);
1038 if (ad_read(devc,11)!=54321) {
1039 printk (KERN_INFO "ad1816: Chip is not an AD1816 (Test 3)\n");
1040 goto out_release_region;
1041 }
1042
1043 /* writes to ireg 10 are copied to ireg 11 */
1044 ad_write(devc,10,12345);
1045 if (ad_read(devc,11)!=12345) {
1046 printk (KERN_INFO "ad1816: Chip is not an AD1816 (Test 4)\n");
1047 goto out_release_region;
1048 }
1049
1050 /* bit in base +1 cannot be set to 1 */
1051 tmp=inb(devc->base+1);
1052 outb(0xff,devc->base+1);
1053 if (inb(devc->base+1)!=tmp) {
1054 printk(KERN_INFO "ad1816: Chip is not an AD1816 (Test 5)\n");
1055 goto out_release_region;
1056 }
1057
1058 printk(KERN_INFO "ad1816: AD1816 (version %d) successfully detected!\n",
1059 ad_read(devc,45));
1060
1061 /* disable all interrupts */
1062 ad_write(devc,1,0);
1063
1064 /* Clear pending interrupts */
1065 outb (0, devc->base+1);
1066
1067 /* allocate irq */
1068 if (devc->irq < 0 || devc->irq > 15)
1069 goto out_release_region;
1070 if (request_irq(devc->irq, ad1816_interrupt,0,
1071 "SoundPort", devc) < 0) {
1072 printk(KERN_WARNING "ad1816: IRQ in use\n");
1073 goto out_release_region;
1074 }
1075
1076 /* DMA stuff */
1077 if (sound_alloc_dma (devc->dma_playback, "Sound System")) {
1078 printk(KERN_WARNING "ad1816: Can't allocate DMA%d\n",
1079 devc->dma_playback);
1080 goto out_free_irq;
1081 }
1082
1083 if ( devc->dma_capture >= 0 &&
1084 devc->dma_capture != devc->dma_playback) {
1085 if (sound_alloc_dma(devc->dma_capture,
1086 "Sound System (capture)")) {
1087 printk(KERN_WARNING "ad1816: Can't allocate DMA%d\n",
1088 devc->dma_capture);
1089 goto out_free_dma;
1090 }
1091 devc->audio_mode=DMA_AUTOMODE|DMA_DUPLEX;
1092 } else {
1093 printk(KERN_WARNING "ad1816: Only one DMA channel "
1094 "available/configured. No duplex operation possible\n");
1095 devc->audio_mode=DMA_AUTOMODE;
1096 }
1097
1098 conf_printf2 ("AD1816 audio driver",
1099 devc->base, devc->irq, devc->dma_playback,
1100 devc->dma_capture);
1101
1102 /* register device */
1103 if ((oss_devno = sound_install_audiodrv (AUDIO_DRIVER_VERSION,
1104 "AD1816 audio driver",
1105 &ad1816_audio_driver,
1106 sizeof (struct audio_driver),
1107 devc->audio_mode,
1108 ad_format_mask,
1109 devc,
1110 devc->dma_playback,
1111 devc->dma_capture)) < 0) {
1112 printk(KERN_WARNING "ad1816: Can't install sound driver\n");
1113 goto out_free_dma_2;
1114 }
1115
1116
1117 ad_write(devc,32,0x80f0); /* sound system mode */
1118 if (options&1) {
1119 ad_write(devc,33,0); /* disable all audiosources for dsp */
1120 } else {
1121 ad_write(devc,33,0x03f8); /* enable all audiosources for dsp */
1122 }
1123 ad_write(devc,4,0x8080); /* default values for volumes (muted)*/
1124 ad_write(devc,5,0x8080);
1125 ad_write(devc,6,0x8080);
1126 ad_write(devc,7,0x8080);
1127 ad_write(devc,15,0x8888);
1128 ad_write(devc,16,0x8888);
1129 ad_write(devc,17,0x8888);
1130 ad_write(devc,18,0x8888);
1131 ad_write(devc,19,0xc888); /* +20db mic active */
1132 ad_write(devc,14,0x0000); /* Master volume unmuted */
1133 ad_write(devc,39,0x009f); /* 3D effect on 0% phone out muted */
1134 ad_write(devc,44,0x0080); /* everything on power, 3d enabled for d/a */
1135 outb(0x10,devc->base+8); /* set dma mode */
1136 outb(0x10,devc->base+9);
1137
1138 /* enable capture + playback interrupt */
1139 ad_write(devc,1,0xc000);
1140
1141 /* set mixer defaults */
1142 ad1816_mixer_reset (devc);
1143
1144 /* register mixer */
1145 if ((audio_devs[oss_devno]->mixer_dev=sound_install_mixer(
1146 MIXER_DRIVER_VERSION,
1147 "AD1816 audio driver",
1148 &ad1816_mixer_operations,
1149 sizeof (struct mixer_operations),
1150 devc)) < 0) {
1151 printk(KERN_WARNING "Can't install mixer\n");
1152 }
1153 /* make ad1816_info active */
1154 nr_ad1816_devs++;
1155 printk(KERN_INFO "ad1816: card successfully installed!\n");
1156 return 1;
1157 /* error handling */
1158out_free_dma_2:
1159 if (devc->dma_capture >= 0 && devc->dma_capture != devc->dma_playback)
1160 sound_free_dma(devc->dma_capture);
1161out_free_dma:
1162 sound_free_dma(devc->dma_playback);
1163out_free_irq:
1164 free_irq(devc->irq, devc);
1165out_release_region:
1166 release_region(devc->base, 16);
1167out:
1168 return 0;
1169}
1170
1171static void __exit unload_card(ad1816_info *devc)
1172{
1173 int mixer, dev = 0;
1174
1175 if (devc != NULL) {
1176 printk("ad1816: Unloading card at address 0x%03x\n",devc->base);
1177
1178 dev = devc->dev_no;
1179 mixer = audio_devs[dev]->mixer_dev;
1180
1181 /* unreg mixer*/
1182 if(mixer>=0) {
1183 sound_unload_mixerdev(mixer);
1184 }
1185 /* unreg audiodev */
1186 sound_unload_audiodev(dev);
1187
1188 /* free dma channels */
1189 if (devc->dma_capture>=0 &&
1190 devc->dma_capture != devc->dma_playback) {
1191 sound_free_dma(devc->dma_capture);
1192 }
1193 sound_free_dma (devc->dma_playback);
1194 /* free irq */
1195 free_irq(devc->irq, devc);
1196 /* free io */
1197 release_region (devc->base, 16);
1198#ifdef __ISAPNP__
1199 if (devc->pnpdev) {
1200 pnp_disable_dev(devc->pnpdev);
1201 pnp_device_detach(devc->pnpdev);
1202 }
1203#endif
1204
1205 } else
1206 printk(KERN_WARNING "ad1816: no device/card specified\n");
1207}
1208
1209static int __initdata io = -1;
1210static int __initdata irq = -1;
1211static int __initdata dma = -1;
1212static int __initdata dma2 = -1;
1213
1214#ifdef __ISAPNP__
1215/* use isapnp for configuration */
1216static int isapnp = 1;
1217static int isapnpjump;
1218module_param(isapnp, bool, 0);
1219module_param(isapnpjump, int, 0);
1220#endif
1221
1222module_param(io, int, 0);
1223module_param(irq, int, 0);
1224module_param(dma, int, 0);
1225module_param(dma2, int, 0);
1226module_param(ad1816_clockfreq, int, 0);
1227module_param(options, int, 0);
1228
1229#ifdef __ISAPNP__
1230static struct {
1231 unsigned short card_vendor, card_device;
1232 unsigned short vendor;
1233 unsigned short function;
1234 struct ad1816_data *data;
1235} isapnp_ad1816_list[] __initdata = {
1236 { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
1237 ISAPNP_VENDOR('A','D','S'), ISAPNP_FUNCTION(0x7150),
1238 NULL },
1239 { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
1240 ISAPNP_VENDOR('A','D','S'), ISAPNP_FUNCTION(0x7180),
1241 NULL },
1242 {0}
1243};
1244
1245MODULE_DEVICE_TABLE(isapnp, isapnp_ad1816_list);
1246
1247
1248static void __init ad1816_config_pnp_card(struct pnp_card *card,
1249 unsigned short vendor,
1250 unsigned short function)
1251{
1252 struct address_info cfg;
1253 struct pnp_dev *card_dev = pnp_find_dev(card, vendor, function, NULL);
1254 if (!card_dev) return;
1255 if (pnp_device_attach(card_dev) < 0) {
1256 printk(KERN_WARNING "ad1816: Failed to attach PnP device\n");
1257 return;
1258 }
1259 if (pnp_activate_dev(card_dev) < 0) {
1260 printk(KERN_WARNING "ad1816: Failed to activate PnP device\n");
1261 pnp_device_detach(card_dev);
1262 return;
1263 }
1264 cfg.io_base = pnp_port_start(card_dev, 2);
1265 cfg.irq = pnp_irq(card_dev, 0);
1266 cfg.dma = pnp_irq(card_dev, 0);
1267 cfg.dma2 = pnp_irq(card_dev, 1);
1268 if (!ad1816_init_card(&cfg, card_dev)) {
1269 pnp_disable_dev(card_dev);
1270 pnp_device_detach(card_dev);
1271 }
1272}
1273
1274static void __init ad1816_config_pnp_cards(void)
1275{
1276 int nr_pnp_cfg;
1277 int i;
1278
1279 /* Count entries in isapnp_ad1816_list */
1280 for (nr_pnp_cfg = 0; isapnp_ad1816_list[nr_pnp_cfg].card_vendor != 0;
1281 nr_pnp_cfg++);
1282 /* Check and adjust isapnpjump */
1283 if( isapnpjump < 0 || isapnpjump >= nr_pnp_cfg) {
1284 printk(KERN_WARNING
1285 "ad1816: Valid range for isapnpjump is 0-%d. "
1286 "Adjusted to 0.\n", nr_pnp_cfg-1);
1287 isapnpjump = 0;
1288 }
1289 for (i = isapnpjump; isapnp_ad1816_list[i].card_vendor != 0; i++) {
1290 struct pnp_card *card = NULL;
1291 /* iterate over all pnp cards */
1292 while ((card = pnp_find_card(isapnp_ad1816_list[i].card_vendor,
1293 isapnp_ad1816_list[i].card_device, card)))
1294 ad1816_config_pnp_card(card,
1295 isapnp_ad1816_list[i].vendor,
1296 isapnp_ad1816_list[i].function);
1297 }
1298}
1299#endif
1300
1301/* module initialization */
1302static int __init init_ad1816(void)
1303{
1304 printk(KERN_INFO "ad1816: AD1816 sounddriver "
1305 "Copyright (C) 1998-2003 by Thorsten Knabe and "
1306 "others\n");
1307#ifdef AD1816_CLOCK
1308 /* set ad1816_clockfreq if set during compilation */
1309 ad1816_clockfreq=AD1816_CLOCK;
1310#endif
1311 if (ad1816_clockfreq<5000 || ad1816_clockfreq>100000) {
1312 ad1816_clockfreq=33000;
1313 }
1314
1315#ifdef __ISAPNP__
1316 /* configure PnP cards */
1317 if(isapnp) ad1816_config_pnp_cards();
1318#endif
1319 /* configure card by module params */
1320 if (io != -1 && irq != -1 && dma != -1) {
1321 struct address_info cfg;
1322 cfg.io_base = io;
1323 cfg.irq = irq;
1324 cfg.dma = dma;
1325 cfg.dma2 = dma2;
1326 ad1816_init_card(&cfg, NULL);
1327 }
1328 if (nr_ad1816_devs <= 0)
1329 return -ENODEV;
1330 return 0;
1331}
1332
1333/* module cleanup */
1334static void __exit cleanup_ad1816 (void)
1335{
1336 int i;
1337 ad1816_info *devc = NULL;
1338
1339 /* remove any soundcard */
1340 for (i = 0; i < nr_ad1816_devs; i++) {
1341 devc = &dev_info[i];
1342 unload_card(devc);
1343 }
1344 nr_ad1816_devs=0;
1345 printk(KERN_INFO "ad1816: driver unloaded!\n");
1346}
1347
1348module_init(init_ad1816);
1349module_exit(cleanup_ad1816);
1350
1351#ifndef MODULE
1352/* kernel command line parameter evaluation */
1353static int __init setup_ad1816(char *str)
1354{
1355 /* io, irq, dma, dma2 */
1356 int ints[5];
1357
1358 str = get_options(str, ARRAY_SIZE(ints), ints);
1359
1360 io = ints[1];
1361 irq = ints[2];
1362 dma = ints[3];
1363 dma2 = ints[4];
1364 return 1;
1365}
1366
1367__setup("ad1816=", setup_ad1816);
1368#endif
1369MODULE_LICENSE("GPL");