Import 2.1.118
[davej-history.git] / drivers / sound / lowlevel / aci.c
blobfc71be47dc6a466359e0a434c656dc3813e10fb9
1 /*
2 * Audio Command Interface (ACI) driver (sound/aci.c)
4 * ACI is a protocol used to communicate with the microcontroller on
5 * some sound cards produced by miro, e.g. the miroSOUND PCM12 and
6 * PCM20. The ACI has been developed for miro by Norberto Pellicci
7 * <pellicci@home.com>. Special thanks to both him and miro for
8 * providing the ACI specification.
10 * The main function of the ACI is to control the mixer and to get a
11 * product identification. On the PCM20, ACI also controls the radio
12 * tuner on this card, this is supported in the Video for Linux
13 * radio-miropcm20 driver.
15 * This Voxware ACI driver currently only supports the ACI functions
16 * on the miroSOUND PCM12 and PCM20 card. Support for miro sound cards
17 * with additional ACI functions can easily be added later.
19 * / NOTE / When compiling as a module, make sure to load the module
20 * after loading the mad16 module. The initialisation code expects the
21 * MAD16 default mixer to be already available.
23 * / NOTE / When compiling as a module, make sure to load the module
24 * after loading the mad16 module. The initialisation code expects the
25 * MAD16 default mixer to be already available.
27 * Revision history:
29 * 1995-11-10 Markus Kuhn <mskuhn@cip.informatik.uni-erlangen.de>
30 * First version written.
31 * 1995-12-31 Markus Kuhn
32 * Second revision, general code cleanup.
33 * 1996-05-16 Hannu Savolainen
34 * Integrated with other parts of the driver.
35 * 1996-05-28 Markus Kuhn
36 * Initialize CS4231A mixer, make ACI first mixer,
37 * use new private mixer API for solo mode.
38 * 1998-08-18 Ruurd Reitsma <R.A.Reitsma@wbmt.tudelft.nl>
39 * Small modification to export ACI functions and
40 * complete modularisation.
44 * Some driver specific information and features:
46 * This mixer driver identifies itself to applications as "ACI" in
47 * mixer_info.id as retrieved by ioctl(fd, SOUND_MIXER_INFO, &mixer_info).
49 * Proprietary mixer features that go beyond the standard OSS mixer
50 * interface are:
52 * Full duplex solo configuration:
54 * int solo_mode;
55 * ioctl(fd, SOUND_MIXER_PRIVATE1, &solo_mode);
57 * solo_mode = 0: deactivate solo mode (default)
58 * solo_mode > 0: activate solo mode
59 * With activated solo mode, the PCM input can not any
60 * longer hear the signals produced by the PCM output.
61 * Activating solo mode is important in duplex mode in order
62 * to avoid feedback distortions.
63 * solo_mode < 0: do not change solo mode (just retrieve the status)
65 * When the ioctl() returns 0, solo_mode contains the previous
66 * status (0 = deactivated, 1 = activated). If solo mode is not
67 * implemented on this card, ioctl() returns -1 and sets errno to
68 * EINVAL.
72 #include <linux/config.h> /* for CONFIG_ACI_MIXER */
73 #include <linux/module.h>
74 #include "lowlevel.h"
75 #include "../sound_config.h"
77 #if defined(CONFIG_ACI_MIXER) || defined(CONFIG_ACI_MIXER_MODULE)
79 #undef DEBUG /* if defined, produce a verbose report via syslog */
81 int aci_port = 0x354; /* as determined by bit 4 in the OPTi 929 MC4 register */
82 unsigned char aci_idcode[2] = {0, 0}; /* manufacturer and product ID */
83 unsigned char aci_version = 0; /* ACI firmware version */
84 int aci_solo; /* status bit of the card that can't be *
85 * checked with ACI versions prior to 0xb0 */
87 static int aci_present = 0;
89 #ifdef MODULE /* Whether the aci mixer is to be reset. */
90 int aci_reset = 0; /* Default: don't reset if the driver is a */
91 MODULE_PARM(aci_reset,"i");
92 #else /* module; use "insmod aci.o aci_reset=1" */
93 int aci_reset = 1; /* to override. */
94 #endif
97 #define COMMAND_REGISTER (aci_port)
98 #define STATUS_REGISTER (aci_port + 1)
99 #define BUSY_REGISTER (aci_port + 2)
102 * Wait until the ACI microcontroller has set the READYFLAG in the
103 * Busy/IRQ Source Register to 0. This is required to avoid
104 * overrunning the sound card microcontroller. We do a busy wait here,
105 * because the microcontroller is not supposed to signal a busy
106 * condition for more than a few clock cycles. In case of a time-out,
107 * this function returns -1.
109 * This busy wait code normally requires less than 15 loops and
110 * practically always less than 100 loops on my i486/DX2 66 MHz.
112 * Warning: Waiting on the general status flag after reseting the MUTE
113 * function can take a VERY long time, because the PCM12 does some kind
114 * of fade-in effect. For this reason, access to the MUTE function has
115 * not been implemented at all.
118 static int busy_wait(void)
120 long timeout;
122 for (timeout = 0; timeout < 10000000L; timeout++)
123 if ((inb_p(BUSY_REGISTER) & 1) == 0)
124 return 0;
126 #ifdef DEBUG
127 printk("ACI: READYFLAG timed out.\n");
128 #endif
130 return -1;
135 * Read the GENERAL STATUS register.
138 static int read_general_status(void)
140 unsigned long flags;
141 int status;
143 save_flags(flags);
144 cli();
145 if (busy_wait()) { restore_flags(flags); return -1; }
146 status = (unsigned) inb_p(STATUS_REGISTER);
147 restore_flags(flags);
148 return status;
153 * The four ACI command types (implied, write, read and indexed) can
154 * be sent to the microcontroller using the following four functions.
155 * If a problem occurred, they return -1.
158 int aci_implied_cmd(unsigned char opcode)
160 unsigned long flags;
162 #ifdef DEBUG
163 printk("ACI: aci_implied_cmd(0x%02x)\n", opcode);
164 #endif
166 save_flags(flags);
167 cli();
169 if (read_general_status() < 0 || busy_wait()) {
170 restore_flags(flags);
171 return -1;
173 outb_p(opcode, COMMAND_REGISTER);
175 restore_flags(flags);
176 return 0;
180 int aci_write_cmd(unsigned char opcode, unsigned char parameter)
182 unsigned long flags;
183 int status;
185 #ifdef DEBUG
186 printk("ACI: aci_write_cmd(0x%02x, 0x%02x)\n", opcode, parameter);
187 #endif
189 save_flags(flags);
190 cli();
192 if (read_general_status() < 0 || busy_wait()) {
193 restore_flags(flags);
194 return -1;
196 outb_p(opcode, COMMAND_REGISTER);
197 if (busy_wait()) { restore_flags(flags); return -1; }
198 outb_p(parameter, COMMAND_REGISTER);
200 if ((status = read_general_status()) < 0) {
201 restore_flags(flags);
202 return -1;
204 /* polarity of the INVALID flag depends on ACI version */
205 if ((aci_version < 0xb0 && (status & 0x40) != 0) ||
206 (aci_version >= 0xb0 && (status & 0x40) == 0)) {
207 restore_flags(flags);
208 printk("ACI: invalid write command 0x%02x, 0x%02x.\n",
209 opcode, parameter);
210 return -1;
213 restore_flags(flags);
214 return 0;
218 * This write command send 2 parameters instead of one.
219 * Only used in PCM20 radio frequency tuning control
222 int aci_write_cmd_d(unsigned char opcode, unsigned char parameter, unsigned char parameter2)
224 unsigned long flags;
225 int status;
227 #ifdef DEBUG
228 printk("ACI: aci_write_cmd_d(0x%02x, 0x%02x)\n", opcode, parameter, parameter2);
229 #endif
231 save_flags(flags);
232 cli();
234 if (read_general_status() < 0 || busy_wait()) {
235 restore_flags(flags);
236 return -1;
238 outb_p(opcode, COMMAND_REGISTER);
239 if (busy_wait()) { restore_flags(flags); return -1; }
240 outb_p(parameter, COMMAND_REGISTER);
241 if (busy_wait()) { restore_flags(flags); return -1; }
242 outb_p(parameter2, COMMAND_REGISTER);
244 if ((status = read_general_status()) < 0) {
245 restore_flags(flags);
246 return -1;
248 /* polarity of the INVALID flag depends on ACI version */
249 if ((aci_version < 0xb0 && (status & 0x40) != 0) ||
250 (aci_version >= 0xb0 && (status & 0x40) == 0)) {
251 restore_flags(flags);
252 #if 0 /* Frequency tuning works, but the INVALID flag is set ??? */
253 printk("ACI: invalid write (double) command 0x%02x, 0x%02x, 0x%02x.\n",
254 opcode, parameter, parameter2);
255 #endif
256 return -1;
259 restore_flags(flags);
260 return 0;
263 int aci_read_cmd(unsigned char opcode, int length, unsigned char *parameter)
265 unsigned long flags;
266 int i = 0;
268 save_flags(flags);
269 cli();
271 if (read_general_status() < 0) { restore_flags(flags); return -1; }
272 while (i < length) {
273 if (busy_wait()) { restore_flags(flags); return -1; }
274 outb_p(opcode, COMMAND_REGISTER);
275 if (busy_wait()) { restore_flags(flags); return -1; }
276 parameter[i++] = inb_p(STATUS_REGISTER);
277 #ifdef DEBUG
278 if (i == 1)
279 printk("ACI: aci_read_cmd(0x%02x, %d) = 0x%02x\n", opcode, length,
280 parameter[i-1]);
281 else
282 printk("ACI: aci_read_cmd cont.: 0x%02x\n", parameter[i-1]);
283 #endif
286 restore_flags(flags);
287 return 0;
291 int aci_indexed_cmd(unsigned char opcode, unsigned char index,
292 unsigned char *parameter)
294 unsigned long flags;
296 save_flags(flags);
297 cli();
299 if (read_general_status() < 0 || busy_wait()) {
300 restore_flags(flags);
301 return -1;
303 outb_p(opcode, COMMAND_REGISTER);
304 if (busy_wait()) { restore_flags(flags); return -1; }
305 outb_p(index, COMMAND_REGISTER);
306 if (busy_wait()) { restore_flags(flags); return -1; }
307 *parameter = inb_p(STATUS_REGISTER);
308 #ifdef DEBUG
309 printk("ACI: aci_indexed_cmd(0x%02x, 0x%02x) = 0x%02x\n", opcode, index,
310 *parameter);
311 #endif
313 restore_flags(flags);
314 return 0;
319 * The following macro SCALE can be used to scale one integer volume
320 * value into another one using only integer arithmetic. If the input
321 * value x is in the range 0 <= x <= xmax, then the result will be in
322 * the range 0 <= SCALE(xmax,ymax,x) <= ymax.
324 * This macro has for all xmax, ymax > 0 and all 0 <= x <= xmax the
325 * following nice properties:
327 * - SCALE(xmax,ymax,xmax) = ymax
328 * - SCALE(xmax,ymax,0) = 0
329 * - SCALE(xmax,ymax,SCALE(ymax,xmax,SCALE(xmax,ymax,x))) = SCALE(xmax,ymax,x)
331 * In addition, the rounding error is minimal and nicely distributed.
332 * The proofs are left as an exercise to the reader.
335 #define SCALE(xmax,ymax,x) (((x)*(ymax)+(xmax)/2)/(xmax))
338 static int getvolume(caddr_t arg,
339 unsigned char left_index, unsigned char right_index)
341 int vol;
342 unsigned char buf;
344 /* left channel */
345 if (aci_indexed_cmd(0xf0, left_index, &buf)) return -EIO;
346 vol = SCALE(0x20, 100, buf < 0x20 ? 0x20-buf : 0);
347 /* right channel */
348 if (aci_indexed_cmd(0xf0, right_index, &buf)) return -EIO;
349 vol |= SCALE(0x20, 100, buf < 0x20 ? 0x20-buf : 0) << 8;
351 return (*(int *) arg = vol);
355 static int setvolume(caddr_t arg,
356 unsigned char left_index, unsigned char right_index)
358 int vol, ret;
360 /* left channel */
361 vol = *(int *)arg & 0xff;
362 if (vol > 100) vol = 100;
363 vol = SCALE(100, 0x20, vol);
364 if (aci_write_cmd(left_index, 0x20 - vol)) return -EIO;
365 ret = SCALE(0x20, 100, vol);
366 /* right channel */
367 vol = (*(int *)arg >> 8) & 0xff;
368 if (vol > 100) vol = 100;
369 vol = SCALE(100, 0x20, vol);
370 if (aci_write_cmd(right_index, 0x20 - vol)) return -EIO;
371 ret |= SCALE(0x20, 100, vol) << 8;
373 return (*(int *) arg = ret);
377 static int
378 aci_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg)
380 int status, vol;
381 unsigned char buf;
383 /* handle solo mode control */
384 if (cmd == SOUND_MIXER_PRIVATE1) {
385 if (*(int *) arg >= 0) {
386 aci_solo = !!*(int *) arg;
387 if (aci_write_cmd(0xd2, aci_solo)) return -EIO;
388 } else if (aci_version >= 0xb0) {
389 if ((status = read_general_status()) < 0) return -EIO;
390 return (*(int *) arg = (status & 0x20) == 0);
392 return (*(int *) arg = aci_solo);
395 if (((cmd >> 8) & 0xff) == 'M') {
396 if (cmd & IOC_IN)
397 /* read and write */
398 switch (cmd & 0xff) {
399 case SOUND_MIXER_VOLUME:
400 return setvolume(arg, 0x01, 0x00);
401 case SOUND_MIXER_CD:
402 return setvolume(arg, 0x3c, 0x34);
403 case SOUND_MIXER_MIC:
404 return setvolume(arg, 0x38, 0x30);
405 case SOUND_MIXER_LINE:
406 return setvolume(arg, 0x39, 0x31);
407 case SOUND_MIXER_SYNTH:
408 return setvolume(arg, 0x3b, 0x33);
409 case SOUND_MIXER_PCM:
410 return setvolume(arg, 0x3a, 0x32);
411 case SOUND_MIXER_LINE1: /* AUX1 */
412 return setvolume(arg, 0x3d, 0x35);
413 case SOUND_MIXER_LINE2: /* AUX2 */
414 return setvolume(arg, 0x3e, 0x36);
415 case SOUND_MIXER_IGAIN: /* MIC pre-amp */
416 vol = *(int *) arg & 0xff;
417 if (vol > 100) vol = 100;
418 vol = SCALE(100, 3, vol);
419 if (aci_write_cmd(0x03, vol)) return -EIO;
420 vol = SCALE(3, 100, vol);
421 return (*(int *) arg = vol | (vol << 8));
422 case SOUND_MIXER_RECSRC:
423 return (*(int *) arg = 0);
424 break;
425 default:
426 return -EINVAL;
428 else
429 /* only read */
430 switch (cmd & 0xff) {
431 case SOUND_MIXER_DEVMASK:
432 return (*(int *) arg =
433 SOUND_MASK_VOLUME | SOUND_MASK_CD |
434 SOUND_MASK_MIC | SOUND_MASK_LINE |
435 SOUND_MASK_SYNTH | SOUND_MASK_PCM |
436 #if 0
437 SOUND_MASK_IGAIN |
438 #endif
439 SOUND_MASK_LINE1 | SOUND_MASK_LINE2);
440 break;
441 case SOUND_MIXER_STEREODEVS:
442 return (*(int *) arg =
443 SOUND_MASK_VOLUME | SOUND_MASK_CD |
444 SOUND_MASK_MIC | SOUND_MASK_LINE |
445 SOUND_MASK_SYNTH | SOUND_MASK_PCM |
446 SOUND_MASK_LINE1 | SOUND_MASK_LINE2);
447 break;
448 case SOUND_MIXER_RECMASK:
449 return (*(int *) arg = 0);
450 break;
451 case SOUND_MIXER_RECSRC:
452 return (*(int *) arg = 0);
453 break;
454 case SOUND_MIXER_CAPS:
455 return (*(int *) arg = 0);
456 break;
457 case SOUND_MIXER_VOLUME:
458 return getvolume(arg, 0x04, 0x03);
459 case SOUND_MIXER_CD:
460 return getvolume(arg, 0x0a, 0x09);
461 case SOUND_MIXER_MIC:
462 return getvolume(arg, 0x06, 0x05);
463 case SOUND_MIXER_LINE:
464 return getvolume(arg, 0x08, 0x07);
465 case SOUND_MIXER_SYNTH:
466 return getvolume(arg, 0x0c, 0x0b);
467 case SOUND_MIXER_PCM:
468 return getvolume(arg, 0x0e, 0x0d);
469 case SOUND_MIXER_LINE1: /* AUX1 */
470 return getvolume(arg, 0x11, 0x10);
471 case SOUND_MIXER_LINE2: /* AUX2 */
472 return getvolume(arg, 0x13, 0x12);
473 case SOUND_MIXER_IGAIN: /* MIC pre-amp */
474 if (aci_indexed_cmd(0xf0, 0x21, &buf)) return -EIO;
475 vol = SCALE(3, 100, buf <= 3 ? buf : 3);
476 vol |= vol << 8;
477 return (*(int *) arg = vol);
478 default:
479 return -EINVAL;
483 return -EINVAL;
487 static struct mixer_operations aci_mixer_operations =
489 "ACI",
490 "ACI mixer",
491 aci_mixer_ioctl,
492 NULL
495 static unsigned char
496 mad_read (int port)
498 outb (0xE3, 0xf8f); /* Write MAD16 password */
499 return inb (port); /* Read from port */
504 * Check, whether there actually is any ACI port operational and if
505 * one was found, then initialize the ACI interface, reserve the I/O
506 * addresses and attach the new mixer to the relevant VoxWare data
507 * structures.
509 * Returns: 1 ACI mixer detected
510 * 0 nothing there
512 * There is also an internal mixer in the codec (CS4231A or AD1845),
513 * that deserves no purpose in an ACI based system which uses an
514 * external ACI controlled stereo mixer. Make sure that this codec
515 * mixer has the AUX1 input selected as the recording source, that the
516 * input gain is set near maximum and that the other channels going
517 * from the inputs to the codec output are muted.
520 int attach_aci(void)
522 char *boardname = "unknown";
523 int volume;
525 #define MC4_PORT 0xf90
527 aci_port =
528 (mad_read(MC4_PORT) & 0x10) ? 0x344 : 0x354;
530 if (check_region(aci_port, 3)) {
531 #ifdef DEBUG
532 printk("ACI: I/O area 0x%03x-0x%03x already used.\n",
533 aci_port, aci_port+2);
534 #endif
535 return 0;
538 if (aci_read_cmd(0xf2, 2, aci_idcode)) {
539 #ifdef DEBUG
540 printk("ACI: Failed to read idcode.\n");
541 #endif
542 return 0;
544 if (aci_read_cmd(0xf1, 1, &aci_version)) {
545 #ifdef DEBUG
546 printk("ACI: Failed to read version.\n");
547 #endif
548 return 0;
551 if (aci_idcode[0] == 0x6d) {
552 /* It looks like a miro sound card. */
553 switch (aci_idcode[1]) {
554 case 0x41:
555 boardname = "PCM1 pro / early PCM12";
556 break;
557 case 0x42:
558 boardname = "PCM12";
559 break;
560 case 0x43:
561 boardname = "PCM20";
562 break;
563 default:
564 boardname = "unknown miro";
566 } else
567 #ifndef DEBUG
568 return 0;
569 #endif
571 printk("<ACI %02x, id %02x %02x (%s)> at 0x%03x\n",
572 aci_version, aci_idcode[0], aci_idcode[1], boardname, aci_port);
574 if (aci_reset) {
575 /* initialize ACI mixer */
576 aci_implied_cmd(0xff);
577 aci_solo = 0;
580 /* attach the mixer */
581 request_region(aci_port, 3, "sound mixer (ACI)");
582 if (num_mixers < MAX_MIXER_DEV) {
583 if (num_mixers > 0 &&
584 !strncmp("MAD16 WSS", mixer_devs[num_mixers-1]->name, 9)) {
586 * The previously registered mixer device is the CS4231A which
587 * has no function on an ACI card. Make the ACI mixer the first
588 * of the two mixer devices.
590 mixer_devs[num_mixers] = mixer_devs[num_mixers-1];
591 mixer_devs[num_mixers-1] = &aci_mixer_operations;
593 * Initialize the CS4231A mixer with reasonable values. It is
594 * unlikely that the user ever will want to change these as all
595 * channels can be mixed via ACI.
597 volume = 0x6464;
598 mixer_devs[num_mixers]->
599 ioctl(num_mixers, SOUND_MIXER_WRITE_PCM, (caddr_t) &volume);
600 volume = 0x6464;
601 mixer_devs[num_mixers]->
602 ioctl(num_mixers, SOUND_MIXER_WRITE_IGAIN, (caddr_t) &volume);
603 volume = 0;
604 mixer_devs[num_mixers]->
605 ioctl(num_mixers, SOUND_MIXER_WRITE_SPEAKER, (caddr_t) &volume);
606 volume = 0;
607 mixer_devs[num_mixers]->
608 ioctl(num_mixers, SOUND_MIXER_WRITE_MIC, (caddr_t) &volume);
609 volume = 0;
610 mixer_devs[num_mixers]->
611 ioctl(num_mixers, SOUND_MIXER_WRITE_IMIX, (caddr_t) &volume);
612 volume = 0;
613 mixer_devs[num_mixers]->
614 ioctl(num_mixers, SOUND_MIXER_WRITE_LINE1, (caddr_t) &volume);
615 volume = 0;
616 mixer_devs[num_mixers]->
617 ioctl(num_mixers, SOUND_MIXER_WRITE_LINE2, (caddr_t) &volume);
618 volume = 0;
619 mixer_devs[num_mixers]->
620 ioctl(num_mixers, SOUND_MIXER_WRITE_LINE3, (caddr_t) &volume);
621 volume = SOUND_MASK_LINE1;
622 mixer_devs[num_mixers]->
623 ioctl(num_mixers, SOUND_MIXER_WRITE_RECSRC, (caddr_t) &volume);
624 num_mixers++;
625 } else
626 mixer_devs[num_mixers++] = &aci_mixer_operations;
629 /* Just do something; otherwise the first write command fails, at
630 * least with my PCM20.
632 aci_mixer_ioctl(num_mixers-1, SOUND_MIXER_READ_VOLUME, (caddr_t) &volume);
634 if (aci_reset) {
635 /* Initialize ACI mixer with reasonable power-up values */
636 volume = 0x3232;
637 aci_mixer_ioctl(num_mixers-1, SOUND_MIXER_WRITE_VOLUME, (caddr_t) &volume);
638 volume = 0x3232;
639 aci_mixer_ioctl(num_mixers-1, SOUND_MIXER_WRITE_SYNTH, (caddr_t) &volume);
640 volume = 0x3232;
641 aci_mixer_ioctl(num_mixers-1, SOUND_MIXER_WRITE_PCM, (caddr_t) &volume);
642 volume = 0x3232;
643 aci_mixer_ioctl(num_mixers-1, SOUND_MIXER_WRITE_LINE, (caddr_t) &volume);
644 volume = 0x3232;
645 aci_mixer_ioctl(num_mixers-1, SOUND_MIXER_WRITE_MIC, (caddr_t) &volume);
646 volume = 0x3232;
647 aci_mixer_ioctl(num_mixers-1, SOUND_MIXER_WRITE_CD, (caddr_t) &volume);
648 volume = 0x3232;
649 aci_mixer_ioctl(num_mixers-1, SOUND_MIXER_WRITE_LINE1, (caddr_t) &volume);
650 volume = 0x3232;
651 aci_mixer_ioctl(num_mixers-1, SOUND_MIXER_WRITE_LINE2, (caddr_t) &volume);
654 aci_present = 1;
656 return 1;
659 void unload_aci(void)
661 if (aci_present)
662 release_region(aci_port, 3);
665 #endif
667 #if defined(MODULE)
669 int init_module(void) {
670 attach_aci();
671 return(0);
674 void cleanup_module(void) {
675 unload_aci();
678 #endif /* MODULE */