1 /*
2 * Mach Operating System
3 * Copyright (c) 1992 Carnegie Mellon University
4 * All Rights Reserved.
5 *
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
11 *
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15 *
16 * Carnegie Mellon requests users of this software to return to
17 *
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
22 *
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
25 */
26 /*
27 * HISTORY
28 * $Log: isdn_79c30_hdw.c,v $
29 * Revision 2.8 93/05/18 10:45:31 rvb
30 * Sadly, the .h files says that audio_attach takes a (audio_switch_t *),
31 * not a (const audio_switch_t *). So you can not make the isdn_ops table
32 * a const.
33 * Type casts, etc to quiet gcc 2.3.3 warnings
34 * [93/05/18 rvb]
35 *
36 * Revision 2.7 93/05/15 19:39:35 mrt
37 * machparam.h -> machspl.h
38 *
39 * Revision 2.6 93/05/10 20:07:58 rvb
40 * No more sys/types.h
41 * [93/05/06 10:02:24 af]
42 *
43 * Revision 2.5 93/03/26 17:58:44 mrt
44 * DEC and GCC disagree on ANSI C.
45 * [93/03/19 af]
46 *
47 * Revision 2.4 93/03/18 10:37:10 mrt
48 * Added include of sys/types.h for old busses.h with caddr_t.
49 * [93/03/18 01:22:51 af]
50 *
51 * Added some real code, taken from Berkeley driver.
52 * Consequently, added Berkeley copyright.
53 * [93/03/12 af]
54 *
55 * Revision 2.2.1.2 93/02/04 01:26:06 af
56 * Changes for Flamingo.
57 * [93/02/04 af]
58 *
59 * Revision 2.2.1.1 92/12/10 15:38:08 af
60 * Proper spl typing.
61 * [92/11/30 af]
62 *
63 * Revision 2.2 92/03/02 18:33:00 rpd
64 * Created stub.
65 * [92/01/19 af]
66 *
67 */
68 /*
69 * File: isdn_79c30_hdw.c
70 * Author: Alessandro Forin, Carnegie Mellon University
71 * Date: 1/92
72 *
73 * Driver for the AMD 79c30 ISDN (Integrated Speech and
74 * Data Network) controller chip.
75 */
76
77 /*-
78 * Copyright (c) 1991, 1992 The Regents of the University of California.
79 * All rights reserved.
80 *
81 * Redistribution and use in source and binary forms, with or without
82 * modification, are permitted provided that the following conditions
83 * are met:
84 * 1. Redistributions of source code must retain the above copyright
85 * notice, this list of conditions and the following disclaimer.
86 * 2. Redistributions in binary form must reproduce the above copyright
87 * notice, this list of conditions and the following disclaimer in the
88 * documentation and/or other materials provided with the distribution.
89 * 3. All advertising materials mentioning features or use of this software
90 * must display the following acknowledgement:
91 * This product includes software developed by the Computer Systems
92 * Engineering Group at Lawrence Berkeley Laboratory.
93 * 4. The name of the Laboratory may not be used to endorse or promote
94 * products derived from this software without specific prior written
95 * permission.
96 *
97 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
98 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
99 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
100 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
101 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
102 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
103 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
104 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
105 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
106 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
107 * SUCH DAMAGE.
108 *
109 * $Header: isdn_79c30_hdw.c,v 2.8 93/05/18 10:45:31 rvb Exp $ (LBL)
110 */
111
112 #include <isdn.h>
113 #if NISDN > 0
114
115 #include <platforms.h>
116
117 #include <mach/std_types.h>
118 #include <machine/machspl.h>
119 #include <sys/ioctl.h> /* for Sun compat */
120 #include <chips/busses.h>
121
122 #include <device/device_types.h>
123 #include <device/io_req.h>
124 #include <device/audio_status.h>
125 #include <chips/audio_defs.h>
126
127 #include <chips/isdn_79c30.h>
128
129 #include <chips/audio_config.h> /* machdep config */
130
131 #define private static
132
133 /*
134 * Autoconf info
135 */
136 private int isdn_probe (vm_offset_t reg, struct bus_ctlr *ui);
137 private void isdn_attach ( struct bus_device *ui);
138
139 private vm_offset_t isdn_std[NISDN] = { 0 };
140 private struct bus_device *isdn_info[NISDN];
141
142 struct bus_driver isdn_driver =
143 { isdn_probe, 0, isdn_attach, 0, isdn_std, "isdn", isdn_info, };
144
145
146 /*
147 * Externally visible functions and data
148 */
149 int isdn_intr();
150
151
152 /*
153 * Status bookeeping and globals
154 */
155 typedef struct {
156 amd79c30_padded_regs_t *regs;
157 void *audio_status; /* for upcalls */
158 struct mapreg sc_map; /* MAP status */
159 /*
160 * keep track of levels so we don't have to convert back from
161 * MAP gain constants
162 */
163 int sc_rlevel; /* record level */
164 int sc_plevel; /* play level */
165 int sc_mlevel; /* monitor level */
166 } isdn_softc_t;
167
168 isdn_softc_t isdn_softc_data[NISDN];
169 isdn_softc_t *isdn_softc[NISDN];
170
171 private int audio_default_level = 150;
172
173
174 /*
175 * Forward decls
176 */
177 audio_switch_t isdn_ops;
178
179 private void isdn_init( isdn_softc_t *sc );
180
181 private void isdn_set_mmr2(
182 register amd79c30_padded_regs_t *regs,
183 register int mmr2);
184
185 private void isdn_setgains(
186 isdn_softc_t *sc,
187 int pgain,
188 int rgain,
189 int mgain);
190
191 /*
192 * Probe chip to see if it is there
193 */
194 private isdn_probe(
195 vm_offset_t reg,
196 struct bus_ctlr *ui)
197 {
198 isdn_softc_t *sc = &isdn_softc_data[ui->unit];
199
200 isdn_softc[ui->unit] = sc;
201 sc->regs = (amd79c30_padded_regs_t *)reg;
202
203 return 1;
204 }
205
206 /*
207 * Attach device to chip-indep driver(s)
208 */
209 private void
210 isdn_attach(
211 struct bus_device *ui)
212 {
213 register isdn_softc_t *sc = isdn_softc[ui->unit];
214 register amd79c30_padded_regs_t *regs = sc->regs;
215
216 /* disable interrupts */
217 write_reg(regs->cr, AMDR_INIT);
218 write_reg(regs->dr, AMD_INIT_PMS_ACTIVE | AMD_INIT_INT_DISABLE);
219
220 /*
221 * Initialize the mux unit. We use MCR3 to route audio (MAP)
222 * through channel Bb. MCR1 and MCR2 are unused.
223 * Setting the INT enable bit in MCR4 will generate an interrupt
224 * on each converted audio sample.
225 */
226 write_reg(regs->cr, AMDR_MUX_1_4);
227 write_reg(regs->dr, 0);
228 write_reg(regs->dr, 0);
229 write_reg(regs->dr, (AMD_MCRCHAN_BB << 4) | AMD_MCRCHAN_BA);
230 write_reg(regs->dr, AMD_MCR4_INT_ENABLE);
231
232 printf(" AMD 79C30A/79C32A");
233
234 audio_attach( sc, &isdn_ops, &sc->audio_status );
235 }
236
237 /*
238 * Chip re-initialization
239 */
240 private void
241 isdn_init(
242 isdn_softc_t *sc)
243 {
244 register amd79c30_padded_regs_t *regs;
245
246 bzero((char *)&sc->sc_map, sizeof sc->sc_map);
247 /* default to speaker */
248 sc->sc_map.mr_mmr2 = AMD_MMR2_AINB | AMD_MMR2_LS;
249
250 /* enable interrupts and set parameters established above */
251 regs = sc->regs;
252 isdn_set_mmr2 (regs, sc->sc_map.mr_mmr2);
253 isdn_setgains (sc, audio_default_level, audio_default_level, 0);
254 write_reg(regs->cr, AMDR_INIT);
255 write_reg(regs->dr, AMD_INIT_PMS_ACTIVE);
256 }
257
258 /*
259 * Chip shutdown
260 */
261 private void
262 isdn_close(
263 isdn_softc_t *sc)
264 {
265 register amd79c30_padded_regs_t *regs;
266
267 regs = sc->regs;
268 write_reg(regs->cr, AMDR_INIT);
269 write_reg(regs->dr, AMD_INIT_PMS_ACTIVE | AMD_INIT_INT_DISABLE);
270 }
271
272 /*
273 * Audio port selection
274 */
275 private void
276 isdn_setport(
277 isdn_softc_t *sc,
278 int port)
279 {
280 if (port == AUDIO_SPEAKER) {
281 sc->sc_map.mr_mmr2 |= AMD_MMR2_LS;
282 isdn_set_mmr2(sc->regs, sc->sc_map.mr_mmr2);
283 } else if (port == AUDIO_HEADPHONE) {
284 sc->sc_map.mr_mmr2 &=~ AMD_MMR2_LS;
285 isdn_set_mmr2(sc->regs, sc->sc_map.mr_mmr2);
286 }
287 }
288
289 private int
290 isdn_getport(
291 isdn_softc_t *sc)
292 {
293 return (sc->sc_map.mr_mmr2 & AMD_MMR2_LS) ?
294 AUDIO_SPEAKER : AUDIO_HEADPHONE;
295 }
296
297 /*
298 * Volume control
299 */
300 private void
301 isdn_setgains(
302 isdn_softc_t *sc,
303 int pgain,
304 int rgain,
305 int mgain)
306 {
307 private void isdn_set_pgain(), isdn_set_rgain(), isdn_set_mgain();
308
309 if (pgain != ~0)
310 isdn_set_pgain(sc, pgain);
311 if (rgain != ~0)
312 isdn_set_rgain(sc, rgain);
313 if (mgain != ~0)
314 isdn_set_mgain(sc, mgain);
315
316 }
317
318 private void
319 isdn_getgains(
320 isdn_softc_t *sc,
321 int *pgain,
322 int *rgain,
323 int *mgain)
324 {
325 *mgain = sc->sc_mlevel;
326 *rgain = sc->sc_rlevel;
327 *pgain = sc->sc_plevel;
328 }
329
330
331 /*
332 * User control over MAP processor
333 */
334 private io_return_t
335 isdn_setstate(
336 isdn_softc_t *sc,
337 dev_flavor_t flavor,
338 register struct mapreg *map,
339 natural_t n_ints)
340 {
341 register amd79c30_padded_regs_t *regs = sc->regs;
342 register int i, v;
343 spl_t s;
344
345 /* Sun compat */
346 if (flavor == AUDIOSETREG) {
347 register struct audio_ioctl *a = (struct audio_ioctl *)map;
348 s = splaudio();
349 write_reg(regs->cr, (a->control >> 8) & 0xff);
350 for (i = 0; i < (a->control & 0xff); i++) {
351 write_reg(regs->dr, a->data[i]);
352 }
353 splx(s);
354 return D_SUCCESS;
355 }
356
357 if (flavor != AUDIO_SETMAP)
358 return D_INVALID_OPERATION;
359
360 if ((n_ints * sizeof(int)) < sizeof(*map))
361 return D_INVALID_SIZE;
362
363 bcopy(map, &sc->sc_map, sizeof(sc->sc_map));
364 sc->sc_map.mr_mmr2 &= 0x7f;
365
366 s = splaudio();
367 write_reg(regs->cr, AMDR_MAP_1_10);
368 for (i = 0; i < 8; i++) {
369 v = map->mr_x[i];
370 WAMD16(regs, v);
371 }
372 for (i = 0; i < 8; ++i) {
373 v = map->mr_r[i];
374 WAMD16(regs, v);
375 }
376 v = map->mr_gx; WAMD16(regs, v);
377 v = map->mr_gr; WAMD16(regs, v);
378 v = map->mr_ger; WAMD16(regs, v);
379 v = map->mr_stgr; WAMD16(regs, v);
380 v = map->mr_ftgr; WAMD16(regs, v);
381 v = map->mr_atgr; WAMD16(regs, v);
382 write_reg(regs->dr, map->mr_mmr1);
383 write_reg(regs->dr, map->mr_mmr2);
384 splx(s);
385 return D_SUCCESS;
386 }
387
388 private io_return_t
389 isdn_getstate(
390 isdn_softc_t *sc,
391 dev_flavor_t flavor,
392 register struct mapreg *map,
393 natural_t *count)
394 {
395 register amd79c30_padded_regs_t *regs = sc->regs;
396 spl_t s;
397 int i;
398
399 /* Sun compat */
400 if (flavor == AUDIOGETREG) {
401 register struct audio_ioctl *a = (struct audio_ioctl *)map;
402 s = splaudio();
403 write_reg(regs->cr, (a->control >> 8) & 0xff);
404 for (i = 0; i < (a->control & 0xff); i++) {
405 read_reg(regs->dr,a->data[i]);
406 }
407 splx(s);
408 *count = sizeof(*a) / sizeof(int);
409 return D_SUCCESS;
410 }
411
412 if ( (*count * sizeof(int)) < sizeof(*map))
413 return D_INVALID_SIZE;
414 bcopy(&sc->sc_map, map, sizeof(sc->sc_map));
415 *count = sizeof(*map) / sizeof(int);
416 return D_SUCCESS;
417 }
418
419
420
421 /*
422 * Set the mmr1 register and one other 16 bit register in the audio chip.
423 * The other register is indicated by op and val.
424 */
425 private void
426 isdn_set_mmr1(
427 register amd79c30_padded_regs_t *regs,
428 register int mmr1,
429 register int op,
430 register int val)
431 {
432 register int s = splaudio();
433
434 write_reg(regs->cr, AMDR_MAP_MMR1);
435 write_reg(regs->dr, mmr1);
436 write_reg(regs->cr, op);
437 WAMD16(regs, val);
438 splx(s);
439 }
440
441 /*
442 * Set the mmr2 register.
443 */
444 private void
445 isdn_set_mmr2(
446 register amd79c30_padded_regs_t *regs,
447 register int mmr2)
448 {
449 register int s = splaudio();
450
451 write_reg(regs->cr, AMDR_MAP_MMR2);
452 write_reg(regs->dr, mmr2);
453 splx(s);
454 }
455
456 /*
457 * gx, gr & stg gains. this table must contain 256 elements with
458 * the 0th being "infinity" (the magic value 9008). The remaining
459 * elements match sun's gain curve (but with higher resolution):
460 * -18 to 0dB in .16dB steps then 0 to 12dB in .08dB steps.
461 */
462 private const unsigned short gx_coeff[256] = {
463 0x9008, 0x8b7c, 0x8b51, 0x8b45, 0x8b42, 0x8b3b, 0x8b36, 0x8b33,
464 0x8b32, 0x8b2a, 0x8b2b, 0x8b2c, 0x8b25, 0x8b23, 0x8b22, 0x8b22,
465 0x9122, 0x8b1a, 0x8aa3, 0x8aa3, 0x8b1c, 0x8aa6, 0x912d, 0x912b,
466 0x8aab, 0x8b12, 0x8aaa, 0x8ab2, 0x9132, 0x8ab4, 0x913c, 0x8abb,
467 0x9142, 0x9144, 0x9151, 0x8ad5, 0x8aeb, 0x8a79, 0x8a5a, 0x8a4a,
468 0x8b03, 0x91c2, 0x91bb, 0x8a3f, 0x8a33, 0x91b2, 0x9212, 0x9213,
469 0x8a2c, 0x921d, 0x8a23, 0x921a, 0x9222, 0x9223, 0x922d, 0x9231,
470 0x9234, 0x9242, 0x925b, 0x92dd, 0x92c1, 0x92b3, 0x92ab, 0x92a4,
471 0x92a2, 0x932b, 0x9341, 0x93d3, 0x93b2, 0x93a2, 0x943c, 0x94b2,
472 0x953a, 0x9653, 0x9782, 0x9e21, 0x9d23, 0x9cd2, 0x9c23, 0x9baa,
473 0x9bde, 0x9b33, 0x9b22, 0x9b1d, 0x9ab2, 0xa142, 0xa1e5, 0x9a3b,
474 0xa213, 0xa1a2, 0xa231, 0xa2eb, 0xa313, 0xa334, 0xa421, 0xa54b,
475 0xada4, 0xac23, 0xab3b, 0xaaab, 0xaa5c, 0xb1a3, 0xb2ca, 0xb3bd,
476 0xbe24, 0xbb2b, 0xba33, 0xc32b, 0xcb5a, 0xd2a2, 0xe31d, 0x0808,
477 0x72ba, 0x62c2, 0x5c32, 0x52db, 0x513e, 0x4cce, 0x43b2, 0x4243,
478 0x41b4, 0x3b12, 0x3bc3, 0x3df2, 0x34bd, 0x3334, 0x32c2, 0x3224,
479 0x31aa, 0x2a7b, 0x2aaa, 0x2b23, 0x2bba, 0x2c42, 0x2e23, 0x25bb,
480 0x242b, 0x240f, 0x231a, 0x22bb, 0x2241, 0x2223, 0x221f, 0x1a33,
481 0x1a4a, 0x1acd, 0x2132, 0x1b1b, 0x1b2c, 0x1b62, 0x1c12, 0x1c32,
482 0x1d1b, 0x1e71, 0x16b1, 0x1522, 0x1434, 0x1412, 0x1352, 0x1323,
483 0x1315, 0x12bc, 0x127a, 0x1235, 0x1226, 0x11a2, 0x1216, 0x0a2a,
484 0x11bc, 0x11d1, 0x1163, 0x0ac2, 0x0ab2, 0x0aab, 0x0b1b, 0x0b23,
485 0x0b33, 0x0c0f, 0x0bb3, 0x0c1b, 0x0c3e, 0x0cb1, 0x0d4c, 0x0ec1,
486 0x079a, 0x0614, 0x0521, 0x047c, 0x0422, 0x03b1, 0x03e3, 0x0333,
487 0x0322, 0x031c, 0x02aa, 0x02ba, 0x02f2, 0x0242, 0x0232, 0x0227,
488 0x0222, 0x021b, 0x01ad, 0x0212, 0x01b2, 0x01bb, 0x01cb, 0x01f6,
489 0x0152, 0x013a, 0x0133, 0x0131, 0x012c, 0x0123, 0x0122, 0x00a2,
490 0x011b, 0x011e, 0x0114, 0x00b1, 0x00aa, 0x00b3, 0x00bd, 0x00ba,
491 0x00c5, 0x00d3, 0x00f3, 0x0062, 0x0051, 0x0042, 0x003b, 0x0033,
492 0x0032, 0x002a, 0x002c, 0x0025, 0x0023, 0x0022, 0x001a, 0x0021,
493 0x001b, 0x001b, 0x001d, 0x0015, 0x0013, 0x0013, 0x0012, 0x0012,
494 0x000a, 0x000a, 0x0011, 0x0011, 0x000b, 0x000b, 0x000c, 0x000e,
495 };
496
497 /*
498 * second stage play gain.
499 */
500 private const unsigned short ger_coeff[] = {
501 0x431f, /* 5. dB */
502 0x331f, /* 5.5 dB */
503 0x40dd, /* 6. dB */
504 0x11dd, /* 6.5 dB */
505 0x440f, /* 7. dB */
506 0x411f, /* 7.5 dB */
507 0x311f, /* 8. dB */
508 0x5520, /* 8.5 dB */
509 0x10dd, /* 9. dB */
510 0x4211, /* 9.5 dB */
511 0x410f, /* 10. dB */
512 0x111f, /* 10.5 dB */
513 0x600b, /* 11. dB */
514 0x00dd, /* 11.5 dB */
515 0x4210, /* 12. dB */
516 0x110f, /* 13. dB */
517 0x7200, /* 14. dB */
518 0x2110, /* 15. dB */
519 0x2200, /* 15.9 dB */
520 0x000b, /* 16.9 dB */
521 0x000f /* 18. dB */
522 #define NGER (sizeof(ger_coeff) / sizeof(ger_coeff[0]))
523 };
524
525 private void
526 isdn_set_rgain(
527 register isdn_softc_t *sc,
528 register int level)
529 {
530 level &= 0xff;
531 sc->sc_rlevel = level;
532 sc->sc_map.mr_mmr1 |= AMD_MMR1_GX;
533 sc->sc_map.mr_gx = gx_coeff[level];
534 isdn_set_mmr1(sc->regs, sc->sc_map.mr_mmr1,
535 AMDR_MAP_GX, sc->sc_map.mr_gx);
536 }
537
538 private void
539 isdn_set_pgain(
540 register isdn_softc_t *sc,
541 register int level)
542 {
543 register int gi, s;
544 register amd79c30_padded_regs_t *regs;
545
546 level &= 0xff;
547 sc->sc_plevel = level;
548 sc->sc_map.mr_mmr1 |= AMD_MMR1_GER|AMD_MMR1_GR;
549 level *= 256 + NGER;
550 level >>= 8;
551 if (level >= 256) {
552 gi = level - 256;
553 level = 255;
554 } else
555 gi = 0;
556 sc->sc_map.mr_ger = ger_coeff[gi];
557 sc->sc_map.mr_gr = gx_coeff[level];
558
559 regs = sc->regs;
560 s = splaudio();
561 write_reg(regs->cr, AMDR_MAP_MMR1);
562 write_reg(regs->dr, sc->sc_map.mr_mmr1);
563 write_reg(regs->cr, AMDR_MAP_GR);
564 gi = sc->sc_map.mr_gr;
565 WAMD16(regs, gi);
566 write_reg(regs->cr, AMDR_MAP_GER);
567 gi = sc->sc_map.mr_ger;
568 WAMD16(regs, gi);
569 splx(s);
570 }
571
572 private void
573 isdn_set_mgain(
574 register isdn_softc_t *sc,
575 register int level)
576 {
577 level &= 0xff;
578 sc->sc_mlevel = level;
579 sc->sc_map.mr_mmr1 |= AMD_MMR1_STG;
580 sc->sc_map.mr_stgr = gx_coeff[level];
581 isdn_set_mmr1(sc->regs, sc->sc_map.mr_mmr1,
582 AMDR_MAP_STG, sc->sc_map.mr_stgr);
583 }
584
585 /*
586 * Interrupt routine
587 */
588 #if old
589 isdn_intr (unit, spllevel)
590 spl_t spllevel;
591 {
592 #ifdef MAXINE
593 xine_enable_interrupt(7, 0, 0);
594 #endif
595 #ifdef FLAMINGO
596 kn15aa_enable_interrupt(12, 0, 0);
597 #endif
598 printf("ISDN interrupt");
599 }
600 #else
601 isdn_intr (unit, spllevel)
602 spl_t spllevel;
603 {
604 isdn_softc_t *sc = isdn_softc[unit];
605 amd79c30_padded_regs_t *regs = sc->regs;
606 register int i;
607 unsigned int c;
608
609 read_reg(regs->ir, i); mb(); /* clear interrupt, now */
610 #if mips
611 splx(spllevel); /* drop priority */
612 #endif
613
614 #if 0
615 if (..this is an audio interrupt..)
616 #endif
617 {
618 read_reg(regs->bbrb, c);
619 if (audio_hwintr(sc->audio_status, c, &c))
620 write_reg(regs->bbtb, c);
621 }
622 }
623 #endif
624
625
626
627 /*
628 * Standard operations vector
629 */
630 audio_switch_t isdn_ops = {
631 isdn_init,
632 isdn_close,
633 isdn_setport,
634 isdn_getport,
635 isdn_setgains,
636 isdn_getgains,
637 isdn_setstate,
638 isdn_getstate
639 };
640
641 #if 1
642 write_an_int(int *where, int what) { *where = what;}
643 read_an_int(int *where) { return *where;}
644 #endif
645
646 #endif
Cache object: bf8d22ee1e6a495c74362fd18827bbf7
|