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.
25 * 1995-11-10 Markus Kuhn <mskuhn@cip.informatik.uni-erlangen.de>
26 * First version written.
27 * 1995-12-31 Markus Kuhn
28 * Second revision, general code cleanup.
29 * 1996-05-16 Hannu Savolainen
30 * Integrated with other parts of the driver.
31 * 1996-05-28 Markus Kuhn
32 * Initialize CS4231A mixer, make ACI first mixer,
33 * use new private mixer API for solo mode.
34 * 1998-08-18 Ruurd Reitsma <R.A.Reitsma@wbmt.tudelft.nl>
35 * Small modification to export ACI functions and
36 * complete modularisation.
40 * Some driver specific information and features:
42 * This mixer driver identifies itself to applications as "ACI" in
43 * mixer_info.id as retrieved by ioctl(fd, SOUND_MIXER_INFO, &mixer_info).
45 * Proprietary mixer features that go beyond the standard OSS mixer
48 * Full duplex solo configuration:
51 * ioctl(fd, SOUND_MIXER_PRIVATE1, &solo_mode);
53 * solo_mode = 0: deactivate solo mode (default)
54 * solo_mode > 0: activate solo mode
55 * With activated solo mode, the PCM input can not any
56 * longer hear the signals produced by the PCM output.
57 * Activating solo mode is important in duplex mode in order
58 * to avoid feedback distortions.
59 * solo_mode < 0: do not change solo mode (just retrieve the status)
61 * When the ioctl() returns 0, solo_mode contains the previous
62 * status (0 = deactivated, 1 = activated). If solo mode is not
63 * implemented on this card, ioctl() returns -1 and sets errno to
68 #include <linux/init.h>
69 #include <linux/module.h>
71 #include "sound_config.h"
73 #undef DEBUG /* if defined, produce a verbose report via syslog */
75 int aci_port
= 0x354; /* as determined by bit 4 in the OPTi 929 MC4 register */
76 unsigned char aci_idcode
[2] = {0, 0}; /* manufacturer and product ID */
77 unsigned char aci_version
= 0; /* ACI firmware version */
78 int aci_solo
; /* status bit of the card that can't be *
79 * checked with ACI versions prior to 0xb0 */
81 static int aci_present
= 0;
83 #ifdef MODULE /* Whether the aci mixer is to be reset. */
84 int aci_reset
= 0; /* Default: don't reset if the driver is a */
85 MODULE_PARM(aci_reset
,"i");
86 #else /* module; use "insmod aci.o aci_reset=1" */
87 int aci_reset
= 1; /* to override. */
91 #define COMMAND_REGISTER (aci_port)
92 #define STATUS_REGISTER (aci_port + 1)
93 #define BUSY_REGISTER (aci_port + 2)
96 * Wait until the ACI microcontroller has set the READYFLAG in the
97 * Busy/IRQ Source Register to 0. This is required to avoid
98 * overrunning the sound card microcontroller. We do a busy wait here,
99 * because the microcontroller is not supposed to signal a busy
100 * condition for more than a few clock cycles. In case of a time-out,
101 * this function returns -1.
103 * This busy wait code normally requires less than 15 loops and
104 * practically always less than 100 loops on my i486/DX2 66 MHz.
106 * Warning: Waiting on the general status flag after reseting the MUTE
107 * function can take a VERY long time, because the PCM12 does some kind
108 * of fade-in effect. For this reason, access to the MUTE function has
109 * not been implemented at all.
112 static int busy_wait(void)
116 for (timeout
= 0; timeout
< 10000000L; timeout
++)
117 if ((inb_p(BUSY_REGISTER
) & 1) == 0)
121 printk("ACI: READYFLAG timed out.\n");
129 * Read the GENERAL STATUS register.
132 static int read_general_status(void)
141 restore_flags(flags
);
145 status
= (unsigned) inb_p(STATUS_REGISTER
);
146 restore_flags(flags
);
152 * The four ACI command types (implied, write, read and indexed) can
153 * be sent to the microcontroller using the following four functions.
154 * If a problem occurred, they return -1.
157 int aci_implied_cmd(unsigned char opcode
)
162 printk("ACI: aci_implied_cmd(0x%02x)\n", opcode
);
168 if (read_general_status() < 0 || busy_wait()) {
169 restore_flags(flags
);
173 outb_p(opcode
, COMMAND_REGISTER
);
175 restore_flags(flags
);
180 int aci_write_cmd(unsigned char opcode
, unsigned char parameter
)
186 printk("ACI: aci_write_cmd(0x%02x, 0x%02x)\n", opcode
, parameter
);
192 if (read_general_status() < 0 || busy_wait()) {
193 restore_flags(flags
);
197 outb_p(opcode
, COMMAND_REGISTER
);
199 restore_flags(flags
);
203 outb_p(parameter
, COMMAND_REGISTER
);
205 if ((status
= read_general_status()) < 0) {
206 restore_flags(flags
);
210 /* polarity of the INVALID flag depends on ACI version */
211 if ((aci_version
< 0xb0 && (status
& 0x40) != 0) ||
212 (aci_version
>= 0xb0 && (status
& 0x40) == 0)) {
213 restore_flags(flags
);
214 printk("ACI: invalid write command 0x%02x, 0x%02x.\n",
219 restore_flags(flags
);
224 * This write command send 2 parameters instead of one.
225 * Only used in PCM20 radio frequency tuning control
228 int aci_write_cmd_d(unsigned char opcode
, unsigned char parameter
, unsigned char parameter2
)
234 printk("ACI: aci_write_cmd_d(0x%02x, 0x%02x)\n", opcode
, parameter
, parameter2
);
240 if (read_general_status() < 0 || busy_wait()) {
241 restore_flags(flags
);
245 outb_p(opcode
, COMMAND_REGISTER
);
247 restore_flags(flags
);
251 outb_p(parameter
, COMMAND_REGISTER
);
253 restore_flags(flags
);
257 outb_p(parameter2
, COMMAND_REGISTER
);
259 if ((status
= read_general_status()) < 0) {
260 restore_flags(flags
);
264 /* polarity of the INVALID flag depends on ACI version */
265 if ((aci_version
< 0xb0 && (status
& 0x40) != 0) ||
266 (aci_version
>= 0xb0 && (status
& 0x40) == 0)) {
267 restore_flags(flags
);
268 #if 0 /* Frequency tuning works, but the INVALID flag is set ??? */
269 printk("ACI: invalid write (double) command 0x%02x, 0x%02x, 0x%02x.\n",
270 opcode
, parameter
, parameter2
);
275 restore_flags(flags
);
279 int aci_read_cmd(unsigned char opcode
, int length
, unsigned char *parameter
)
287 if (read_general_status() < 0) {
288 restore_flags(flags
);
293 restore_flags(flags
);
297 outb_p(opcode
, COMMAND_REGISTER
);
299 restore_flags(flags
);
303 parameter
[i
++] = inb_p(STATUS_REGISTER
);
306 printk("ACI: aci_read_cmd(0x%02x, %d) = 0x%02x\n",
307 opcode
, length
, parameter
[i
-1]);
309 printk("ACI: aci_read_cmd cont.: 0x%02x\n", parameter
[i
-1]);
313 restore_flags(flags
);
318 int aci_indexed_cmd(unsigned char opcode
, unsigned char index
,
319 unsigned char *parameter
)
326 if (read_general_status() < 0 || busy_wait()) {
327 restore_flags(flags
);
331 outb_p(opcode
, COMMAND_REGISTER
);
333 restore_flags(flags
);
337 outb_p(index
, COMMAND_REGISTER
);
339 restore_flags(flags
);
343 *parameter
= inb_p(STATUS_REGISTER
);
345 printk("ACI: aci_indexed_cmd(0x%02x, 0x%02x) = 0x%02x\n", opcode
, index
,
349 restore_flags(flags
);
355 * The following macro SCALE can be used to scale one integer volume
356 * value into another one using only integer arithmetic. If the input
357 * value x is in the range 0 <= x <= xmax, then the result will be in
358 * the range 0 <= SCALE(xmax,ymax,x) <= ymax.
360 * This macro has for all xmax, ymax > 0 and all 0 <= x <= xmax the
361 * following nice properties:
363 * - SCALE(xmax,ymax,xmax) = ymax
364 * - SCALE(xmax,ymax,0) = 0
365 * - SCALE(xmax,ymax,SCALE(ymax,xmax,SCALE(xmax,ymax,x))) = SCALE(xmax,ymax,x)
367 * In addition, the rounding error is minimal and nicely distributed.
368 * The proofs are left as an exercise to the reader.
371 #define SCALE(xmax,ymax,x) (((x)*(ymax)+(xmax)/2)/(xmax))
374 static int getvolume(caddr_t arg
,
375 unsigned char left_index
, unsigned char right_index
)
381 if (aci_indexed_cmd(0xf0, left_index
, &buf
))
383 vol
= SCALE(0x20, 100, buf
< 0x20 ? 0x20-buf
: 0);
386 if (aci_indexed_cmd(0xf0, right_index
, &buf
))
388 vol
|= SCALE(0x20, 100, buf
< 0x20 ? 0x20-buf
: 0) << 8;
390 return (*(int *) arg
= vol
);
394 static int setvolume(caddr_t arg
,
395 unsigned char left_index
, unsigned char right_index
)
400 vol
= *(int *)arg
& 0xff;
403 vol
= SCALE(100, 0x20, vol
);
404 if (aci_write_cmd(left_index
, 0x20 - vol
))
406 ret
= SCALE(0x20, 100, vol
);
410 vol
= (*(int *)arg
>> 8) & 0xff;
413 vol
= SCALE(100, 0x20, vol
);
414 if (aci_write_cmd(right_index
, 0x20 - vol
))
416 ret
|= SCALE(0x20, 100, vol
) << 8;
418 return (*(int *) arg
= ret
);
423 aci_mixer_ioctl (int dev
, unsigned int cmd
, caddr_t arg
)
428 /* handle solo mode control */
429 if (cmd
== SOUND_MIXER_PRIVATE1
) {
430 if (*(int *) arg
>= 0) {
431 aci_solo
= !!*(int *) arg
;
432 if (aci_write_cmd(0xd2, aci_solo
))
434 } else if (aci_version
>= 0xb0) {
435 if ((status
= read_general_status()) < 0)
437 return (*(int *) arg
= (status
& 0x20) == 0);
440 return (*(int *) arg
= aci_solo
);
443 if (((cmd
>> 8) & 0xff) == 'M') {
446 switch (cmd
& 0xff) {
447 case SOUND_MIXER_VOLUME
:
448 return setvolume(arg
, 0x01, 0x00);
450 return setvolume(arg
, 0x3c, 0x34);
451 case SOUND_MIXER_MIC
:
452 return setvolume(arg
, 0x38, 0x30);
453 case SOUND_MIXER_LINE
:
454 return setvolume(arg
, 0x39, 0x31);
455 case SOUND_MIXER_SYNTH
:
456 return setvolume(arg
, 0x3b, 0x33);
457 case SOUND_MIXER_PCM
:
458 return setvolume(arg
, 0x3a, 0x32);
459 case SOUND_MIXER_LINE1
: /* AUX1 */
460 return setvolume(arg
, 0x3d, 0x35);
461 case SOUND_MIXER_LINE2
: /* AUX2 */
462 return setvolume(arg
, 0x3e, 0x36);
463 case SOUND_MIXER_IGAIN
: /* MIC pre-amp */
464 vol
= *(int *) arg
& 0xff;
467 vol
= SCALE(100, 3, vol
);
468 if (aci_write_cmd(0x03, vol
))
470 vol
= SCALE(3, 100, vol
);
471 return (*(int *) arg
= vol
| (vol
<< 8));
472 case SOUND_MIXER_RECSRC
:
473 return (*(int *) arg
= 0);
480 switch (cmd
& 0xff) {
481 case SOUND_MIXER_DEVMASK
:
482 return (*(int *) arg
=
483 SOUND_MASK_VOLUME
| SOUND_MASK_CD
|
484 SOUND_MASK_MIC
| SOUND_MASK_LINE
|
485 SOUND_MASK_SYNTH
| SOUND_MASK_PCM
|
489 SOUND_MASK_LINE1
| SOUND_MASK_LINE2
);
491 case SOUND_MIXER_STEREODEVS
:
492 return (*(int *) arg
=
493 SOUND_MASK_VOLUME
| SOUND_MASK_CD
|
494 SOUND_MASK_MIC
| SOUND_MASK_LINE
|
495 SOUND_MASK_SYNTH
| SOUND_MASK_PCM
|
496 SOUND_MASK_LINE1
| SOUND_MASK_LINE2
);
498 case SOUND_MIXER_RECMASK
:
499 return (*(int *) arg
= 0);
501 case SOUND_MIXER_RECSRC
:
502 return (*(int *) arg
= 0);
504 case SOUND_MIXER_CAPS
:
505 return (*(int *) arg
= 0);
507 case SOUND_MIXER_VOLUME
:
508 return getvolume(arg
, 0x04, 0x03);
510 return getvolume(arg
, 0x0a, 0x09);
511 case SOUND_MIXER_MIC
:
512 return getvolume(arg
, 0x06, 0x05);
513 case SOUND_MIXER_LINE
:
514 return getvolume(arg
, 0x08, 0x07);
515 case SOUND_MIXER_SYNTH
:
516 return getvolume(arg
, 0x0c, 0x0b);
517 case SOUND_MIXER_PCM
:
518 return getvolume(arg
, 0x0e, 0x0d);
519 case SOUND_MIXER_LINE1
: /* AUX1 */
520 return getvolume(arg
, 0x11, 0x10);
521 case SOUND_MIXER_LINE2
: /* AUX2 */
522 return getvolume(arg
, 0x13, 0x12);
523 case SOUND_MIXER_IGAIN
: /* MIC pre-amp */
524 if (aci_indexed_cmd(0xf0, 0x21, &buf
))
526 vol
= SCALE(3, 100, buf
<= 3 ? buf
: 3);
528 return (*(int *) arg
= vol
);
538 static struct mixer_operations aci_mixer_operations
=
549 outb (0xE3, 0xf8f); /* Write MAD16 password */
550 return inb (port
); /* Read from port */
555 * Check, whether there actually is any ACI port operational and if
556 * one was found, then initialize the ACI interface, reserve the I/O
557 * addresses and attach the new mixer to the relevant VoxWare data
560 * Returns: 1 ACI mixer detected
563 * There is also an internal mixer in the codec (CS4231A or AD1845),
564 * that deserves no purpose in an ACI based system which uses an
565 * external ACI controlled stereo mixer. Make sure that this codec
566 * mixer has the AUX1 input selected as the recording source, that the
567 * input gain is set near maximum and that the other channels going
568 * from the inputs to the codec output are muted.
571 static int __init
attach_aci(void)
573 char *boardname
= "unknown";
576 #define MC4_PORT 0xf90
579 (mad_read(MC4_PORT
) & 0x10) ? 0x344 : 0x354;
581 if (check_region(aci_port
, 3)) {
583 printk("ACI: I/O area 0x%03x-0x%03x already used.\n",
584 aci_port
, aci_port
+2);
589 if (aci_read_cmd(0xf2, 2, aci_idcode
)) {
591 printk("ACI: Failed to read idcode.\n");
596 if (aci_read_cmd(0xf1, 1, &aci_version
)) {
598 printk("ACI: Failed to read version.\n");
603 if (aci_idcode
[0] == 0x6d) {
604 /* It looks like a miro sound card. */
605 switch (aci_idcode
[1]) {
607 boardname
= "PCM1 pro / early PCM12";
616 boardname
= "unknown miro";
623 printk("<ACI %02x, id %02x %02x (%s)> at 0x%03x\n",
624 aci_version
, aci_idcode
[0], aci_idcode
[1], boardname
, aci_port
);
627 /* initialize ACI mixer */
628 aci_implied_cmd(0xff);
632 /* attach the mixer */
633 request_region(aci_port
, 3, "sound mixer (ACI)");
634 if (num_mixers
< MAX_MIXER_DEV
) {
635 if (num_mixers
> 0 &&
636 !strncmp("MAD16 WSS", mixer_devs
[num_mixers
-1]->name
, 9)) {
638 * The previously registered mixer device is the CS4231A which
639 * has no function on an ACI card. Make the ACI mixer the first
640 * of the two mixer devices.
642 mixer_devs
[num_mixers
] = mixer_devs
[num_mixers
-1];
643 mixer_devs
[num_mixers
-1] = &aci_mixer_operations
;
645 * Initialize the CS4231A mixer with reasonable values. It is
646 * unlikely that the user ever will want to change these as all
647 * channels can be mixed via ACI.
650 mixer_devs
[num_mixers
]->ioctl(num_mixers
,
651 SOUND_MIXER_WRITE_PCM
, (caddr_t
) &volume
);
653 mixer_devs
[num_mixers
]->ioctl(num_mixers
,
654 SOUND_MIXER_WRITE_IGAIN
, (caddr_t
) &volume
);
656 mixer_devs
[num_mixers
]->ioctl(num_mixers
,
657 SOUND_MIXER_WRITE_SPEAKER
, (caddr_t
) &volume
);
659 mixer_devs
[num_mixers
]->ioctl(num_mixers
,
660 SOUND_MIXER_WRITE_MIC
, (caddr_t
) &volume
);
662 mixer_devs
[num_mixers
]->ioctl(num_mixers
,
663 SOUND_MIXER_WRITE_IMIX
, (caddr_t
) &volume
);
665 mixer_devs
[num_mixers
]->ioctl(num_mixers
,
666 SOUND_MIXER_WRITE_LINE1
, (caddr_t
) &volume
);
668 mixer_devs
[num_mixers
]->ioctl(num_mixers
,
669 SOUND_MIXER_WRITE_LINE2
, (caddr_t
) &volume
);
671 mixer_devs
[num_mixers
]->ioctl(num_mixers
,
672 SOUND_MIXER_WRITE_LINE3
, (caddr_t
) &volume
);
673 volume
= SOUND_MASK_LINE1
;
674 mixer_devs
[num_mixers
]->ioctl(num_mixers
,
675 SOUND_MIXER_WRITE_RECSRC
, (caddr_t
) &volume
);
678 mixer_devs
[num_mixers
++] = &aci_mixer_operations
;
681 /* Just do something; otherwise the first write command fails, at
682 * least with my PCM20.
684 aci_mixer_ioctl(num_mixers
-1, SOUND_MIXER_READ_VOLUME
, (caddr_t
) &volume
);
687 /* Initialize ACI mixer with reasonable power-up values */
689 aci_mixer_ioctl(num_mixers
-1, SOUND_MIXER_WRITE_VOLUME
, (caddr_t
) &volume
);
691 aci_mixer_ioctl(num_mixers
-1, SOUND_MIXER_WRITE_SYNTH
, (caddr_t
) &volume
);
693 aci_mixer_ioctl(num_mixers
-1, SOUND_MIXER_WRITE_PCM
, (caddr_t
) &volume
);
695 aci_mixer_ioctl(num_mixers
-1, SOUND_MIXER_WRITE_LINE
, (caddr_t
) &volume
);
697 aci_mixer_ioctl(num_mixers
-1, SOUND_MIXER_WRITE_MIC
, (caddr_t
) &volume
);
699 aci_mixer_ioctl(num_mixers
-1, SOUND_MIXER_WRITE_CD
, (caddr_t
) &volume
);
701 aci_mixer_ioctl(num_mixers
-1, SOUND_MIXER_WRITE_LINE1
, (caddr_t
) &volume
);
703 aci_mixer_ioctl(num_mixers
-1, SOUND_MIXER_WRITE_LINE2
, (caddr_t
) &volume
);
711 static void __exit
unload_aci(void)
714 release_region(aci_port
, 3);
717 module_init(attach_aci
);
718 module_exit(unload_aci
);