Deleted Added
full compact
ad1816.c (67652) ad1816.c (70134)
1/*
2 * Copyright (c) 1999 Cameron Grant <gandalf@vilnya.demon.co.uk>
3 * Copyright Luigi Rizzo, 1997,1998
4 * Copyright by Hannu Savolainen 1994, 1995
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 11 unchanged lines hidden (view full) ---

20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
1/*
2 * Copyright (c) 1999 Cameron Grant <gandalf@vilnya.demon.co.uk>
3 * Copyright Luigi Rizzo, 1997,1998
4 * Copyright by Hannu Savolainen 1994, 1995
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 11 unchanged lines hidden (view full) ---

20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 * $FreeBSD: head/sys/dev/sound/isa/ad1816.c 67652 2000-10-26 20:46:58Z cg $
28 * $FreeBSD: head/sys/dev/sound/isa/ad1816.c 70134 2000-12-18 01:36:41Z cg $
29 */
30
31#include <dev/sound/pcm/sound.h>
32#include <dev/sound/isa/ad1816.h>
33
29 */
30
31#include <dev/sound/pcm/sound.h>
32#include <dev/sound/isa/ad1816.h>
33
34#include "mixer_if.h"
35
34struct ad1816_info;
35
36struct ad1816_chinfo {
37 struct ad1816_info *parent;
38 pcm_channel *channel;
39 snd_dbuf *buffer;
40 int dir;
41};

--- 17 unchanged lines hidden (view full) ---

59static int ad1816_probe(device_t dev);
60static int ad1816_attach(device_t dev);
61
62/* IO primitives */
63static int ad1816_wait_init(struct ad1816_info *ad1816, int x);
64static u_short ad1816_read(struct ad1816_info *ad1816, u_int reg);
65static void ad1816_write(struct ad1816_info *ad1816, u_int reg, u_short data);
66
36struct ad1816_info;
37
38struct ad1816_chinfo {
39 struct ad1816_info *parent;
40 pcm_channel *channel;
41 snd_dbuf *buffer;
42 int dir;
43};

--- 17 unchanged lines hidden (view full) ---

61static int ad1816_probe(device_t dev);
62static int ad1816_attach(device_t dev);
63
64/* IO primitives */
65static int ad1816_wait_init(struct ad1816_info *ad1816, int x);
66static u_short ad1816_read(struct ad1816_info *ad1816, u_int reg);
67static void ad1816_write(struct ad1816_info *ad1816, u_int reg, u_short data);
68
67static int ad1816mix_init(snd_mixer *m);
68static int ad1816mix_set(snd_mixer *m, unsigned dev, unsigned left, unsigned right);
69static int ad1816mix_setrecsrc(snd_mixer *m, u_int32_t src);
70static snd_mixer ad1816_mixer = {
71 "ad1816 mixer",
72 ad1816mix_init,
73 NULL,
74 NULL,
75 ad1816mix_set,
76 ad1816mix_setrecsrc,
77};
78
79static devclass_t pcm_devclass;
80
69static devclass_t pcm_devclass;
70
81/* channel interface */
82static void *ad1816chan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir);
83static int ad1816chan_setdir(void *data, int dir);
84static int ad1816chan_setformat(void *data, u_int32_t format);
85static int ad1816chan_setspeed(void *data, u_int32_t speed);
86static int ad1816chan_setblocksize(void *data, u_int32_t blocksize);
87static int ad1816chan_trigger(void *data, int go);
88static int ad1816chan_getptr(void *data);
89static pcmchan_caps *ad1816chan_getcaps(void *data);
90
91static u_int32_t ad1816_fmt[] = {
92 AFMT_U8,
93 AFMT_STEREO | AFMT_U8,
94 AFMT_S16_LE,
95 AFMT_STEREO | AFMT_S16_LE,
96 AFMT_MU_LAW,
97 AFMT_STEREO | AFMT_MU_LAW,
98 AFMT_A_LAW,
99 AFMT_STEREO | AFMT_A_LAW,
100 0
101};
102
103static pcmchan_caps ad1816_caps = {4000, 55200, ad1816_fmt, 0};
104
71static u_int32_t ad1816_fmt[] = {
72 AFMT_U8,
73 AFMT_STEREO | AFMT_U8,
74 AFMT_S16_LE,
75 AFMT_STEREO | AFMT_S16_LE,
76 AFMT_MU_LAW,
77 AFMT_STEREO | AFMT_MU_LAW,
78 AFMT_A_LAW,
79 AFMT_STEREO | AFMT_A_LAW,
80 0
81};
82
83static pcmchan_caps ad1816_caps = {4000, 55200, ad1816_fmt, 0};
84
105static pcm_channel ad1816_chantemplate = {
106 ad1816chan_init,
107 ad1816chan_setdir,
108 ad1816chan_setformat,
109 ad1816chan_setspeed,
110 ad1816chan_setblocksize,
111 ad1816chan_trigger,
112 ad1816chan_getptr,
113 ad1816chan_getcaps,
114 NULL, /* free */
115 NULL, /* nop1 */
116 NULL, /* nop2 */
117 NULL, /* nop3 */
118 NULL, /* nop4 */
119 NULL, /* nop5 */
120 NULL, /* nop6 */
121 NULL, /* nop7 */
122};
123
124#define AD1816_MUTE 31 /* value for mute */
125
126static int
127port_rd(struct resource *port, int off)
128{
129 if (port)
130 return bus_space_read_1(rman_get_bustag(port),
131 rman_get_bushandle(port),

--- 95 unchanged lines hidden (view full) ---

227 flags = spltty();
228 if (ad1816_wait_init(ad1816, 100) == -1) return;
229 io_wr(ad1816, AD1816_ALE, (reg & AD1816_ALEMASK));
230 io_wr(ad1816, AD1816_LOW, (data & 0x000000ff));
231 io_wr(ad1816, AD1816_HIGH, (data & 0x0000ff00) >> 8);
232 splx(flags);
233}
234
85#define AD1816_MUTE 31 /* value for mute */
86
87static int
88port_rd(struct resource *port, int off)
89{
90 if (port)
91 return bus_space_read_1(rman_get_bustag(port),
92 rman_get_bushandle(port),

--- 95 unchanged lines hidden (view full) ---

188 flags = spltty();
189 if (ad1816_wait_init(ad1816, 100) == -1) return;
190 io_wr(ad1816, AD1816_ALE, (reg & AD1816_ALEMASK));
191 io_wr(ad1816, AD1816_LOW, (data & 0x000000ff));
192 io_wr(ad1816, AD1816_HIGH, (data & 0x0000ff00) >> 8);
193 splx(flags);
194}
195
196/* -------------------------------------------------------------------- */
197
235static int
236ad1816mix_init(snd_mixer *m)
237{
238 mix_setdevs(m, AD1816_MIXER_DEVICES);
239 mix_setrecdevs(m, AD1816_REC_DEVICES);
240 return 0;
241}
242

--- 81 unchanged lines hidden (view full) ---

324 src = SOUND_MASK_MIC;
325 }
326
327 dev |= dev << 8;
328 ad1816_write(ad1816, 20, (ad1816_read(ad1816, 20) & ~0x7070) | dev);
329 return src;
330}
331
198static int
199ad1816mix_init(snd_mixer *m)
200{
201 mix_setdevs(m, AD1816_MIXER_DEVICES);
202 mix_setrecdevs(m, AD1816_REC_DEVICES);
203 return 0;
204}
205

--- 81 unchanged lines hidden (view full) ---

287 src = SOUND_MASK_MIC;
288 }
289
290 dev |= dev << 8;
291 ad1816_write(ad1816, 20, (ad1816_read(ad1816, 20) & ~0x7070) | dev);
292 return src;
293}
294
295static kobj_method_t ad1816mixer_methods[] = {
296 KOBJMETHOD(mixer_init, ad1816mix_init),
297 KOBJMETHOD(mixer_set, ad1816mix_set),
298 KOBJMETHOD(mixer_setrecsrc, ad1816mix_setrecsrc),
299 { 0, 0 }
300};
301MIXER_DECLARE(ad1816mixer);
302
303/* -------------------------------------------------------------------- */
332/* channel interface */
333static void *
304/* channel interface */
305static void *
334ad1816chan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
306ad1816chan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
335{
336 struct ad1816_info *ad1816 = devinfo;
337 struct ad1816_chinfo *ch = (dir == PCMDIR_PLAY)? &ad1816->pch : &ad1816->rch;
338
339 ch->parent = ad1816;
340 ch->channel = c;
341 ch->buffer = b;
342 ch->buffer->bufsize = DSP_BUFFSIZE;
343 if (chn_allocbuf(ch->buffer, ad1816->parent_dmat) == -1) return NULL;
344 return ch;
345}
346
347static int
307{
308 struct ad1816_info *ad1816 = devinfo;
309 struct ad1816_chinfo *ch = (dir == PCMDIR_PLAY)? &ad1816->pch : &ad1816->rch;
310
311 ch->parent = ad1816;
312 ch->channel = c;
313 ch->buffer = b;
314 ch->buffer->bufsize = DSP_BUFFSIZE;
315 if (chn_allocbuf(ch->buffer, ad1816->parent_dmat) == -1) return NULL;
316 return ch;
317}
318
319static int
348ad1816chan_setdir(void *data, int dir)
320ad1816chan_setdir(kobj_t obj, void *data, int dir)
349{
350 struct ad1816_chinfo *ch = data;
351 struct ad1816_info *ad1816 = ch->parent;
352
353 ch->buffer->chan = rman_get_start((dir == PCMDIR_PLAY)?
354 ad1816->drq1 : ad1816->drq2);
355 ch->dir = dir;
356 return 0;
357}
358
359static int
321{
322 struct ad1816_chinfo *ch = data;
323 struct ad1816_info *ad1816 = ch->parent;
324
325 ch->buffer->chan = rman_get_start((dir == PCMDIR_PLAY)?
326 ad1816->drq1 : ad1816->drq2);
327 ch->dir = dir;
328 return 0;
329}
330
331static int
360ad1816chan_setformat(void *data, u_int32_t format)
332ad1816chan_setformat(kobj_t obj, void *data, u_int32_t format)
361{
362 struct ad1816_chinfo *ch = data;
363 struct ad1816_info *ad1816 = ch->parent;
364
365 int fmt = AD1816_U8, reg;
366 if (ch->dir == PCMDIR_PLAY) {
367 reg = AD1816_PLAY;
368 ad1816_write(ad1816, 8, 0x0000); /* reset base and current counter */

--- 25 unchanged lines hidden (view full) ---

394 break;
395 }
396 if (format & AFMT_STEREO) fmt |= AD1816_STEREO;
397 io_wr(ad1816, reg, fmt);
398 return format;
399}
400
401static int
333{
334 struct ad1816_chinfo *ch = data;
335 struct ad1816_info *ad1816 = ch->parent;
336
337 int fmt = AD1816_U8, reg;
338 if (ch->dir == PCMDIR_PLAY) {
339 reg = AD1816_PLAY;
340 ad1816_write(ad1816, 8, 0x0000); /* reset base and current counter */

--- 25 unchanged lines hidden (view full) ---

366 break;
367 }
368 if (format & AFMT_STEREO) fmt |= AD1816_STEREO;
369 io_wr(ad1816, reg, fmt);
370 return format;
371}
372
373static int
402ad1816chan_setspeed(void *data, u_int32_t speed)
374ad1816chan_setspeed(kobj_t obj, void *data, u_int32_t speed)
403{
404 struct ad1816_chinfo *ch = data;
405 struct ad1816_info *ad1816 = ch->parent;
406
407 RANGE(speed, 4000, 55200);
408 ad1816_write(ad1816, (ch->dir == PCMDIR_PLAY)? 2 : 3, speed);
409 return speed;
410}
411
412static int
375{
376 struct ad1816_chinfo *ch = data;
377 struct ad1816_info *ad1816 = ch->parent;
378
379 RANGE(speed, 4000, 55200);
380 ad1816_write(ad1816, (ch->dir == PCMDIR_PLAY)? 2 : 3, speed);
381 return speed;
382}
383
384static int
413ad1816chan_setblocksize(void *data, u_int32_t blocksize)
385ad1816chan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
414{
415 return blocksize;
416}
417
418static int
386{
387 return blocksize;
388}
389
390static int
419ad1816chan_trigger(void *data, int go)
391ad1816chan_trigger(kobj_t obj, void *data, int go)
420{
421 struct ad1816_chinfo *ch = data;
422 struct ad1816_info *ad1816 = ch->parent;
423 int wr, reg;
424
425 if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD)
426 return 0;
427

--- 33 unchanged lines hidden (view full) ---

461 ad1816_write(ad1816, wr? 9 : 11, 0); /* reset cur cnt */
462 }
463 break;
464 }
465 return 0;
466}
467
468static int
392{
393 struct ad1816_chinfo *ch = data;
394 struct ad1816_info *ad1816 = ch->parent;
395 int wr, reg;
396
397 if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD)
398 return 0;
399

--- 33 unchanged lines hidden (view full) ---

433 ad1816_write(ad1816, wr? 9 : 11, 0); /* reset cur cnt */
434 }
435 break;
436 }
437 return 0;
438}
439
440static int
469ad1816chan_getptr(void *data)
441ad1816chan_getptr(kobj_t obj, void *data)
470{
471 struct ad1816_chinfo *ch = data;
472 return buf_isadmaptr(ch->buffer);
473}
474
475static pcmchan_caps *
442{
443 struct ad1816_chinfo *ch = data;
444 return buf_isadmaptr(ch->buffer);
445}
446
447static pcmchan_caps *
476ad1816chan_getcaps(void *data)
448ad1816chan_getcaps(kobj_t obj, void *data)
477{
478 return &ad1816_caps;
479}
480
449{
450 return &ad1816_caps;
451}
452
453static kobj_method_t ad1816chan_methods[] = {
454 KOBJMETHOD(channel_init, ad1816chan_init),
455 KOBJMETHOD(channel_setdir, ad1816chan_setdir),
456 KOBJMETHOD(channel_setformat, ad1816chan_setformat),
457 KOBJMETHOD(channel_setspeed, ad1816chan_setspeed),
458 KOBJMETHOD(channel_setblocksize, ad1816chan_setblocksize),
459 KOBJMETHOD(channel_trigger, ad1816chan_trigger),
460 KOBJMETHOD(channel_getptr, ad1816chan_getptr),
461 KOBJMETHOD(channel_getcaps, ad1816chan_getcaps),
462 { 0, 0 }
463};
464CHANNEL_DECLARE(ad1816chan);
465
466/* -------------------------------------------------------------------- */
467
481static void
482ad1816_release_resources(struct ad1816_info *ad1816, device_t dev)
483{
484 if (ad1816->irq) {
485 if (ad1816->ih)
486 bus_teardown_intr(dev, ad1816->irq, ad1816->ih);
487 bus_release_resource(dev, SYS_RES_IRQ, ad1816->irq_rid,
488 ad1816->irq);

--- 102 unchanged lines hidden (view full) ---

591
592 ad1816->io_rid = 2;
593 ad1816->irq_rid = 0;
594 ad1816->drq1_rid = 0;
595 ad1816->drq2_rid = 1;
596
597 if (!ad1816_alloc_resources(ad1816, dev)) goto no;
598 ad1816_init(ad1816, dev);
468static void
469ad1816_release_resources(struct ad1816_info *ad1816, device_t dev)
470{
471 if (ad1816->irq) {
472 if (ad1816->ih)
473 bus_teardown_intr(dev, ad1816->irq, ad1816->ih);
474 bus_release_resource(dev, SYS_RES_IRQ, ad1816->irq_rid,
475 ad1816->irq);

--- 102 unchanged lines hidden (view full) ---

578
579 ad1816->io_rid = 2;
580 ad1816->irq_rid = 0;
581 ad1816->drq1_rid = 0;
582 ad1816->drq2_rid = 1;
583
584 if (!ad1816_alloc_resources(ad1816, dev)) goto no;
585 ad1816_init(ad1816, dev);
599 mixer_init(dev, &ad1816_mixer, ad1816);
586 if (mixer_init(dev, &ad1816mixer_class, ad1816)) goto no;
587
600 bus_setup_intr(dev, ad1816->irq, INTR_TYPE_TTY, ad1816_intr, ad1816, &ad1816->ih);
601 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
602 /*lowaddr*/BUS_SPACE_MAXADDR_24BIT,
603 /*highaddr*/BUS_SPACE_MAXADDR,
604 /*filter*/NULL, /*filterarg*/NULL,
605 /*maxsize*/DSP_BUFFSIZE, /*nsegments*/1,
606 /*maxsegz*/0x3ffff,
607 /*flags*/0, &ad1816->parent_dmat) != 0) {

--- 4 unchanged lines hidden (view full) ---

612 rman_get_start(ad1816->io_base),
613 rman_get_start(ad1816->irq),
614 rman_get_start(ad1816->drq1));
615 if (ad1816->drq2) snprintf(status + strlen(status),
616 SND_STATUSLEN - strlen(status), ":%ld",
617 rman_get_start(ad1816->drq2));
618
619 if (pcm_register(dev, ad1816, 1, 1)) goto no;
588 bus_setup_intr(dev, ad1816->irq, INTR_TYPE_TTY, ad1816_intr, ad1816, &ad1816->ih);
589 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
590 /*lowaddr*/BUS_SPACE_MAXADDR_24BIT,
591 /*highaddr*/BUS_SPACE_MAXADDR,
592 /*filter*/NULL, /*filterarg*/NULL,
593 /*maxsize*/DSP_BUFFSIZE, /*nsegments*/1,
594 /*maxsegz*/0x3ffff,
595 /*flags*/0, &ad1816->parent_dmat) != 0) {

--- 4 unchanged lines hidden (view full) ---

600 rman_get_start(ad1816->io_base),
601 rman_get_start(ad1816->irq),
602 rman_get_start(ad1816->drq1));
603 if (ad1816->drq2) snprintf(status + strlen(status),
604 SND_STATUSLEN - strlen(status), ":%ld",
605 rman_get_start(ad1816->drq2));
606
607 if (pcm_register(dev, ad1816, 1, 1)) goto no;
620 pcm_addchan(dev, PCMDIR_REC, &ad1816_chantemplate, ad1816);
621 pcm_addchan(dev, PCMDIR_PLAY, &ad1816_chantemplate, ad1816);
608 pcm_addchan(dev, PCMDIR_REC, &ad1816chan_class, ad1816);
609 pcm_addchan(dev, PCMDIR_PLAY, &ad1816chan_class, ad1816);
622 pcm_setstatus(dev, status);
623
624 return 0;
625no:
626 ad1816_release_resources(ad1816, dev);
627 return ENXIO;
628
629}

--- 36 unchanged lines hidden ---
610 pcm_setstatus(dev, status);
611
612 return 0;
613no:
614 ad1816_release_resources(ad1816, dev);
615 return ENXIO;
616
617}

--- 36 unchanged lines hidden ---