Import 2.1.41
[davej-history.git] / drivers / sound / lowlevel / aci.c
blob7599d5a6ce381a639978a64fe33db034f21bfffa
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@ix.netcom.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, however this is not yet supported in this
13 * software.
15 * This Voxware ACI driver currently only supports the ACI functions
16 * on the miroSOUND PCM12 card. Support for miro soundcards with
17 * additional ACI functions can easily be added later.
19 * Revision history:
21 * 1995-11-10 Markus Kuhn <mskuhn@cip.informatik.uni-erlangen.de>
22 * First version written.
23 * 1995-12-31 Markus Kuhn
24 * Second revision, general code cleanup.
25 * 1996-05-16 Hannu Savolainen
26 * Integrated with other parts of the driver.
27 * 1996-05-28 Markus Kuhn
28 * Initialize CS4231A mixer, make ACI first mixer,
29 * use new private mixer API for solo mode.
33 * Some driver specific information and features:
35 * This mixer driver identifies itself to applications as "ACI" in
36 * mixer_info.id as retrieved by ioctl(fd, SOUND_MIXER_INFO, &mixer_info).
38 * Proprietary mixer features that go beyond the standard OSS mixer
39 * interface are:
41 * Full duplex solo configuration:
43 * int solo_mode;
44 * ioctl(fd, SOUND_MIXER_PRIVATE1, &solo_mode);
46 * solo_mode = 0: deactivate solo mode (default)
47 * solo_mode > 0: activate solo mode
48 * With activated solo mode, the PCM input can not any
49 * longer hear the signals produced by the PCM output.
50 * Activating solo mode is important in duplex mode in order
51 * to avoid feedback distortions.
52 * solo_mode < 0: do not change solo mode (just retrieve the status)
54 * When the ioctl() returns 0, solo_mode contains the previous
55 * status (0 = deactivated, 1 = activated). If solo mode is not
56 * implemented on this card, ioctl() returns -1 and sets errno to
57 * EINVAL.
61 #include "lowlevel.h"
62 #include "../sound_config.h"
63 #include "lowlevel.h"
64 #ifdef CONFIG_ACI_MIXER
66 #undef DEBUG /* if defined, produce a verbose report via syslog */
68 int aci_port = 0x354; /* as determined by bit 4 in the OPTi 929 MC4 register */
69 unsigned char aci_idcode[2] = {0, 0}; /* manufacturer and product ID */
70 unsigned char aci_version = 0; /* ACI firmware version */
71 int aci_solo; /* status bit of the card that can't be *
72 * checked with ACI versions prior to 0xb0 */
74 static int aci_present = 0;
76 #ifdef MODULE /* Whether the aci mixer is to be reset. */
77 int aci_reset = 0; /* Default: don't reset if the driver is a */
78 #else /* module; use "insmod sound.o aci_reset=1" */
79 int aci_reset = 1; /* to override. */
80 #endif
83 #define COMMAND_REGISTER (aci_port)
84 #define STATUS_REGISTER (aci_port + 1)
85 #define BUSY_REGISTER (aci_port + 2)
88 * Wait until the ACI microcontroller has set the READYFLAG in the
89 * Busy/IRQ Source Register to 0. This is required to avoid
90 * overrunning the soundcard microcontroller. We do a busy wait here,
91 * because the microcontroller is not supposed to signal a busy
92 * condition for more than a few clock cycles. In case of a time-out,
93 * this function returns -1.
95 * This busy wait code normally requires less than 15 loops and
96 * practically always less than 100 loops on my i486/DX2 66 MHz.
98 * Warning: Waiting on the general status flag after reseting the MUTE
99 * function can take a VERY long time, because the PCM12 does some kind
100 * of fade-in effect. For this reason, access to the MUTE function has
101 * not been implemented at all.
104 static int busy_wait(void)
106 long timeout;
108 for (timeout = 0; timeout < 10000000L; timeout++)
109 if ((inb_p(BUSY_REGISTER) & 1) == 0)
110 return 0;
112 #ifdef DEBUG
113 printk("ACI: READYFLAG timed out.\n");
114 #endif
116 return -1;
121 * Read the GENERAL STATUS register.
124 static int read_general_status(void)
126 unsigned long flags;
127 int status;
129 save_flags(flags);
130 cli();
131 if (busy_wait()) { restore_flags(flags); return -1; }
132 status = (unsigned) inb_p(STATUS_REGISTER);
133 restore_flags(flags);
134 return status;
139 * The four ACI command types (implied, write, read and indexed) can
140 * be sent to the microcontroller using the following four functions.
141 * If a problem occurred, they return -1.
144 static int implied_cmd(unsigned char opcode)
146 unsigned long flags;
148 #ifdef DEBUG
149 printk("ACI: implied_cmd(0x%02x)\n", opcode);
150 #endif
152 save_flags(flags);
153 cli();
155 if (read_general_status() < 0 || busy_wait()) {
156 restore_flags(flags);
157 return -1;
159 outb_p(opcode, COMMAND_REGISTER);
161 restore_flags(flags);
162 return 0;
166 static int write_cmd(unsigned char opcode, unsigned char parameter)
168 unsigned long flags;
169 int status;
171 #ifdef DEBUG
172 printk("ACI: write_cmd(0x%02x, 0x%02x)\n", opcode, parameter);
173 #endif
175 save_flags(flags);
176 cli();
178 if (read_general_status() < 0 || busy_wait()) {
179 restore_flags(flags);
180 return -1;
182 outb_p(opcode, COMMAND_REGISTER);
183 if (busy_wait()) { restore_flags(flags); return -1; }
184 outb_p(parameter, COMMAND_REGISTER);
186 if ((status = read_general_status()) < 0) {
187 restore_flags(flags);
188 return -1;
190 /* polarity of the INVALID flag depends on ACI version */
191 if ((aci_version < 0xb0 && (status & 0x40) != 0) ||
192 (aci_version >= 0xb0 && (status & 0x40) == 0)) {
193 restore_flags(flags);
194 printk("ACI: invalid write command 0x%02x, 0x%02x.\n",
195 opcode, parameter);
196 return -1;
199 restore_flags(flags);
200 return 0;
204 static int read_cmd(unsigned char opcode, int length, unsigned char *parameter)
206 unsigned long flags;
207 int i = 0;
209 save_flags(flags);
210 cli();
212 if (read_general_status() < 0) { restore_flags(flags); return -1; }
213 while (i < length) {
214 if (busy_wait()) { restore_flags(flags); return -1; }
215 outb_p(opcode, COMMAND_REGISTER);
216 if (busy_wait()) { restore_flags(flags); return -1; }
217 parameter[i++] = inb_p(STATUS_REGISTER);
218 #ifdef DEBUG
219 if (i == 1)
220 printk("ACI: read_cmd(0x%02x, %d) = 0x%02x\n", opcode, length,
221 parameter[i-1]);
222 else
223 printk("ACI: read_cmd cont.: 0x%02x\n", parameter[i-1]);
224 #endif
227 restore_flags(flags);
228 return 0;
232 static int indexed_cmd(unsigned char opcode, unsigned char index,
233 unsigned char *parameter)
235 unsigned long flags;
237 save_flags(flags);
238 cli();
240 if (read_general_status() < 0 || busy_wait()) {
241 restore_flags(flags);
242 return -1;
244 outb_p(opcode, COMMAND_REGISTER);
245 if (busy_wait()) { restore_flags(flags); return -1; }
246 outb_p(index, COMMAND_REGISTER);
247 if (busy_wait()) { restore_flags(flags); return -1; }
248 *parameter = inb_p(STATUS_REGISTER);
249 #ifdef DEBUG
250 printk("ACI: indexed_cmd(0x%02x, 0x%02x) = 0x%02x\n", opcode, index,
251 *parameter);
252 #endif
254 restore_flags(flags);
255 return 0;
260 * The following macro SCALE can be used to scale one integer volume
261 * value into another one using only integer arithmetic. If the input
262 * value x is in the range 0 <= x <= xmax, then the result will be in
263 * the range 0 <= SCALE(xmax,ymax,x) <= ymax.
265 * This macro has for all xmax, ymax > 0 and all 0 <= x <= xmax the
266 * following nice properties:
268 * - SCALE(xmax,ymax,xmax) = ymax
269 * - SCALE(xmax,ymax,0) = 0
270 * - SCALE(xmax,ymax,SCALE(ymax,xmax,SCALE(xmax,ymax,x))) = SCALE(xmax,ymax,x)
272 * In addition, the rounding error is minimal and nicely distributed.
273 * The proofs are left as an exercise to the reader.
276 #define SCALE(xmax,ymax,x) (((x)*(ymax)+(xmax)/2)/(xmax))
279 static int getvolume(caddr_t arg,
280 unsigned char left_index, unsigned char right_index)
282 int vol;
283 unsigned char buf;
285 /* left channel */
286 if (indexed_cmd(0xf0, left_index, &buf)) return -EIO;
287 vol = SCALE(0x20, 100, buf < 0x20 ? 0x20-buf : 0);
288 /* right channel */
289 if (indexed_cmd(0xf0, right_index, &buf)) return -EIO;
290 vol |= SCALE(0x20, 100, buf < 0x20 ? 0x20-buf : 0) << 8;
292 return (*(int *) arg = vol);
296 static int setvolume(caddr_t arg,
297 unsigned char left_index, unsigned char right_index)
299 int vol, ret;
301 /* left channel */
302 vol = *(int *)arg & 0xff;
303 if (vol > 100) vol = 100;
304 vol = SCALE(100, 0x20, vol);
305 if (write_cmd(left_index, 0x20 - vol)) return -EIO;
306 ret = SCALE(0x20, 100, vol);
307 /* right channel */
308 vol = (*(int *)arg >> 8) & 0xff;
309 if (vol > 100) vol = 100;
310 vol = SCALE(100, 0x20, vol);
311 if (write_cmd(right_index, 0x20 - vol)) return -EIO;
312 ret |= SCALE(0x20, 100, vol) << 8;
314 return (*(int *) arg = ret);
318 static int
319 aci_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg)
321 int status, vol;
322 unsigned char buf;
324 /* handle solo mode control */
325 if (cmd == SOUND_MIXER_PRIVATE1) {
326 if (*(int *) arg >= 0) {
327 aci_solo = !!*(int *) arg;
328 if (write_cmd(0xd2, aci_solo)) return -EIO;
329 } else if (aci_version >= 0xb0) {
330 if ((status = read_general_status()) < 0) return -EIO;
331 return (*(int *) arg = (status & 0x20) == 0);
333 return (*(int *) arg = aci_solo);
336 if (((cmd >> 8) & 0xff) == 'M') {
337 if (cmd & IOC_IN)
338 /* read and write */
339 switch (cmd & 0xff) {
340 case SOUND_MIXER_VOLUME:
341 return setvolume(arg, 0x01, 0x00);
342 case SOUND_MIXER_CD:
343 return setvolume(arg, 0x3c, 0x34);
344 case SOUND_MIXER_MIC:
345 return setvolume(arg, 0x38, 0x30);
346 case SOUND_MIXER_LINE:
347 return setvolume(arg, 0x39, 0x31);
348 case SOUND_MIXER_SYNTH:
349 return setvolume(arg, 0x3b, 0x33);
350 case SOUND_MIXER_PCM:
351 return setvolume(arg, 0x3a, 0x32);
352 case SOUND_MIXER_LINE1: /* AUX1 */
353 return setvolume(arg, 0x3d, 0x35);
354 case SOUND_MIXER_LINE2: /* AUX2 */
355 return setvolume(arg, 0x3e, 0x36);
356 case SOUND_MIXER_IGAIN: /* MIC pre-amp */
357 vol = *(int *) arg & 0xff;
358 if (vol > 100) vol = 100;
359 vol = SCALE(100, 3, vol);
360 if (write_cmd(0x03, vol)) return -EIO;
361 vol = SCALE(3, 100, vol);
362 return (*(int *) arg = vol | (vol << 8));
363 case SOUND_MIXER_RECSRC:
364 return (*(int *) arg = 0);
365 break;
366 default:
367 return -EINVAL;
369 else
370 /* only read */
371 switch (cmd & 0xff) {
372 case SOUND_MIXER_DEVMASK:
373 return (*(int *) arg =
374 SOUND_MASK_VOLUME | SOUND_MASK_CD |
375 SOUND_MASK_MIC | SOUND_MASK_LINE |
376 SOUND_MASK_SYNTH | SOUND_MASK_PCM |
377 #if 0
378 SOUND_MASK_IGAIN |
379 #endif
380 SOUND_MASK_LINE1 | SOUND_MASK_LINE2);
381 break;
382 case SOUND_MIXER_STEREODEVS:
383 return (*(int *) arg =
384 SOUND_MASK_VOLUME | SOUND_MASK_CD |
385 SOUND_MASK_MIC | SOUND_MASK_LINE |
386 SOUND_MASK_SYNTH | SOUND_MASK_PCM |
387 SOUND_MASK_LINE1 | SOUND_MASK_LINE2);
388 break;
389 case SOUND_MIXER_RECMASK:
390 return (*(int *) arg = 0);
391 break;
392 case SOUND_MIXER_RECSRC:
393 return (*(int *) arg = 0);
394 break;
395 case SOUND_MIXER_CAPS:
396 return (*(int *) arg = 0);
397 break;
398 case SOUND_MIXER_VOLUME:
399 return getvolume(arg, 0x04, 0x03);
400 case SOUND_MIXER_CD:
401 return getvolume(arg, 0x0a, 0x09);
402 case SOUND_MIXER_MIC:
403 return getvolume(arg, 0x06, 0x05);
404 case SOUND_MIXER_LINE:
405 return getvolume(arg, 0x08, 0x07);
406 case SOUND_MIXER_SYNTH:
407 return getvolume(arg, 0x0c, 0x0b);
408 case SOUND_MIXER_PCM:
409 return getvolume(arg, 0x0e, 0x0d);
410 case SOUND_MIXER_LINE1: /* AUX1 */
411 return getvolume(arg, 0x11, 0x10);
412 case SOUND_MIXER_LINE2: /* AUX2 */
413 return getvolume(arg, 0x13, 0x12);
414 case SOUND_MIXER_IGAIN: /* MIC pre-amp */
415 if (indexed_cmd(0xf0, 0x21, &buf)) return -EIO;
416 vol = SCALE(3, 100, buf <= 3 ? buf : 3);
417 vol |= vol << 8;
418 return (*(int *) arg = vol);
419 default:
420 return -EINVAL;
424 return -EINVAL;
428 static struct mixer_operations aci_mixer_operations =
430 "ACI",
431 "ACI mixer",
432 aci_mixer_ioctl,
433 NULL
436 static unsigned char
437 mad_read (int port)
439 outb (0xE3, 0xf8f); /* Write MAD16 password */
440 return inb (port); /* Read from port */
445 * Check, whether there actually is any ACI port operational and if
446 * one was found, then initialize the ACI interface, reserve the I/O
447 * addresses and attach the new mixer to the relevant VoxWare data
448 * structures.
450 * Returns: 1 ACI mixer detected
451 * 0 nothing there
453 * There is also an internal mixer in the codec (CS4231A or AD1845),
454 * that deserves no purpose in an ACI based system which uses an
455 * external ACI controlled stereo mixer. Make sure that this codec
456 * mixer has the AUX1 input selected as the recording source, that the
457 * input gain is set near maximum and that the other channels going
458 * from the inputs to the codec output are muted.
461 int attach_aci(void)
463 char *boardname = "unknown";
464 int volume;
466 #define MC4_PORT 0xf90
468 aci_port =
469 (mad_read(MC4_PORT) & 0x10) ? 0x344 : 0x354;
471 if (check_region(aci_port, 3)) {
472 #ifdef DEBUG
473 printk("ACI: I/O area 0x%03x-0x%03x already used.\n",
474 aci_port, aci_port+2);
475 #endif
476 return 0;
479 if (read_cmd(0xf2, 2, aci_idcode)) {
480 #ifdef DEBUG
481 printk("ACI: Failed to read idcode.\n");
482 #endif
483 return 0;
485 if (read_cmd(0xf1, 1, &aci_version)) {
486 #ifdef DEBUG
487 printk("ACI: Failed to read version.\n");
488 #endif
489 return 0;
492 if (aci_idcode[0] == 0x6d) {
493 /* it looks like a miro soundcard */
494 switch (aci_idcode[1]) {
495 case 0x41:
496 boardname = "PCM1 pro / early PCM12";
497 break;
498 case 0x42:
499 boardname = "PCM12";
500 break;
501 case 0x43:
502 boardname = "PCM20";
503 break;
504 default:
505 boardname = "unknown miro";
507 } else
508 #ifndef DEBUG
509 return 0;
510 #endif
512 printk("<ACI %02x, id %02x %02x (%s)> at 0x%03x\n",
513 aci_version, aci_idcode[0], aci_idcode[1], boardname, aci_port);
515 if (aci_reset) {
516 /* initialize ACI mixer */
517 implied_cmd(0xff);
518 aci_solo = 0;
521 /* attach the mixer */
522 request_region(aci_port, 3, "sound mixer (ACI)");
523 if (num_mixers < MAX_MIXER_DEV) {
524 if (num_mixers > 0 &&
525 !strncmp("MAD16 WSS", mixer_devs[num_mixers-1]->name, 9)) {
527 * The previously registered mixer device is the CS4231A which
528 * has no function on an ACI card. Make the ACI mixer the first
529 * of the two mixer devices.
531 mixer_devs[num_mixers] = mixer_devs[num_mixers-1];
532 mixer_devs[num_mixers-1] = &aci_mixer_operations;
534 * Initialize the CS4231A mixer with reasonable values. It is
535 * unlikely that the user ever will want to change these as all
536 * channels can be mixed via ACI.
538 volume = 0x6464;
539 mixer_devs[num_mixers]->
540 ioctl(num_mixers, SOUND_MIXER_WRITE_PCM, (caddr_t) &volume);
541 volume = 0x6464;
542 mixer_devs[num_mixers]->
543 ioctl(num_mixers, SOUND_MIXER_WRITE_IGAIN, (caddr_t) &volume);
544 volume = 0;
545 mixer_devs[num_mixers]->
546 ioctl(num_mixers, SOUND_MIXER_WRITE_SPEAKER, (caddr_t) &volume);
547 volume = 0;
548 mixer_devs[num_mixers]->
549 ioctl(num_mixers, SOUND_MIXER_WRITE_MIC, (caddr_t) &volume);
550 volume = 0;
551 mixer_devs[num_mixers]->
552 ioctl(num_mixers, SOUND_MIXER_WRITE_IMIX, (caddr_t) &volume);
553 volume = 0;
554 mixer_devs[num_mixers]->
555 ioctl(num_mixers, SOUND_MIXER_WRITE_LINE1, (caddr_t) &volume);
556 volume = 0;
557 mixer_devs[num_mixers]->
558 ioctl(num_mixers, SOUND_MIXER_WRITE_LINE2, (caddr_t) &volume);
559 volume = 0;
560 mixer_devs[num_mixers]->
561 ioctl(num_mixers, SOUND_MIXER_WRITE_LINE3, (caddr_t) &volume);
562 volume = SOUND_MASK_LINE1;
563 mixer_devs[num_mixers]->
564 ioctl(num_mixers, SOUND_MIXER_WRITE_RECSRC, (caddr_t) &volume);
565 num_mixers++;
566 } else
567 mixer_devs[num_mixers++] = &aci_mixer_operations;
570 /* Just do something; otherwise the first write command fails, at
571 * least with my PCM20.
573 aci_mixer_ioctl(num_mixers-1, SOUND_MIXER_READ_VOLUME, (caddr_t) &volume);
575 if (aci_reset) {
576 /* Initialize ACI mixer with reasonable power-up values */
577 volume = 0x3232;
578 aci_mixer_ioctl(num_mixers-1, SOUND_MIXER_WRITE_VOLUME, (caddr_t) &volume);
579 volume = 0x3232;
580 aci_mixer_ioctl(num_mixers-1, SOUND_MIXER_WRITE_SYNTH, (caddr_t) &volume);
581 volume = 0x3232;
582 aci_mixer_ioctl(num_mixers-1, SOUND_MIXER_WRITE_PCM, (caddr_t) &volume);
583 volume = 0x3232;
584 aci_mixer_ioctl(num_mixers-1, SOUND_MIXER_WRITE_LINE, (caddr_t) &volume);
585 volume = 0x3232;
586 aci_mixer_ioctl(num_mixers-1, SOUND_MIXER_WRITE_MIC, (caddr_t) &volume);
587 volume = 0x3232;
588 aci_mixer_ioctl(num_mixers-1, SOUND_MIXER_WRITE_CD, (caddr_t) &volume);
589 volume = 0x3232;
590 aci_mixer_ioctl(num_mixers-1, SOUND_MIXER_WRITE_LINE1, (caddr_t) &volume);
591 volume = 0x3232;
592 aci_mixer_ioctl(num_mixers-1, SOUND_MIXER_WRITE_LINE2, (caddr_t) &volume);
595 aci_present = 1;
597 return 1;
600 void unload_aci(void)
602 if (aci_present)
603 release_region(aci_port, 3);
606 #endif