| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: audio.c,v 1.28.2.2 2019/10/06 11:00:15 martin Exp $ */ | | 1 | /* $NetBSD: audio.c,v 1.28.2.3 2019/10/06 11:02:32 martin Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2008 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2008 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Andrew Doran. | | 8 | * by Andrew Doran. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -132,27 +132,27 @@ | | | @@ -132,27 +132,27 @@ |
132 | * these may be also called after attach, the thread lock is required. | | 132 | * these may be also called after attach, the thread lock is required. |
133 | * | | 133 | * |
134 | * In addition, there is an additional lock. | | 134 | * In addition, there is an additional lock. |
135 | * | | 135 | * |
136 | * - track->lock. This is an atomic variable and is similar to the | | 136 | * - track->lock. This is an atomic variable and is similar to the |
137 | * "interrupt lock". This is one for each track. If any thread context | | 137 | * "interrupt lock". This is one for each track. If any thread context |
138 | * (and software interrupt context) and hardware interrupt context who | | 138 | * (and software interrupt context) and hardware interrupt context who |
139 | * want to access some variables on this track, they must acquire this | | 139 | * want to access some variables on this track, they must acquire this |
140 | * lock before. It protects track's consistency between hardware | | 140 | * lock before. It protects track's consistency between hardware |
141 | * interrupt context and others. | | 141 | * interrupt context and others. |
142 | */ | | 142 | */ |
143 | | | 143 | |
144 | #include <sys/cdefs.h> | | 144 | #include <sys/cdefs.h> |
145 | __KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.28.2.2 2019/10/06 11:00:15 martin Exp $"); | | 145 | __KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.28.2.3 2019/10/06 11:02:32 martin Exp $"); |
146 | | | 146 | |
147 | #ifdef _KERNEL_OPT | | 147 | #ifdef _KERNEL_OPT |
148 | #include "audio.h" | | 148 | #include "audio.h" |
149 | #include "midi.h" | | 149 | #include "midi.h" |
150 | #endif | | 150 | #endif |
151 | | | 151 | |
152 | #if NAUDIO > 0 | | 152 | #if NAUDIO > 0 |
153 | | | 153 | |
154 | #ifdef _KERNEL | | 154 | #ifdef _KERNEL |
155 | | | 155 | |
156 | #include <sys/types.h> | | 156 | #include <sys/types.h> |
157 | #include <sys/param.h> | | 157 | #include <sys/param.h> |
158 | #include <sys/atomic.h> | | 158 | #include <sys/atomic.h> |
| @@ -4611,75 +4611,75 @@ audio_mixer_init(struct audio_softc *sc, | | | @@ -4611,75 +4611,75 @@ audio_mixer_init(struct audio_softc *sc, |
4611 | mixer->volume = 256; | | 4611 | mixer->volume = 256; |
4612 | mixer->blktime_d = 1000; | | 4612 | mixer->blktime_d = 1000; |
4613 | mixer->blktime_n = audio_mixer_calc_blktime(sc, mixer); | | 4613 | mixer->blktime_n = audio_mixer_calc_blktime(sc, mixer); |
4614 | sc->sc_blk_ms = mixer->blktime_n; | | 4614 | sc->sc_blk_ms = mixer->blktime_n; |
4615 | hwblks = NBLKHW; | | 4615 | hwblks = NBLKHW; |
4616 | | | 4616 | |
4617 | mixer->frames_per_block = frame_per_block(mixer, &mixer->hwbuf.fmt); | | 4617 | mixer->frames_per_block = frame_per_block(mixer, &mixer->hwbuf.fmt); |
4618 | blksize = frametobyte(&mixer->hwbuf.fmt, mixer->frames_per_block); | | 4618 | blksize = frametobyte(&mixer->hwbuf.fmt, mixer->frames_per_block); |
4619 | if (sc->hw_if->round_blocksize) { | | 4619 | if (sc->hw_if->round_blocksize) { |
4620 | int rounded; | | 4620 | int rounded; |
4621 | audio_params_t p = format2_to_params(&mixer->hwbuf.fmt); | | 4621 | audio_params_t p = format2_to_params(&mixer->hwbuf.fmt); |
4622 | rounded = sc->hw_if->round_blocksize(sc->hw_hdl, blksize, | | 4622 | rounded = sc->hw_if->round_blocksize(sc->hw_hdl, blksize, |
4623 | mode, &p); | | 4623 | mode, &p); |
4624 | TRACE(2, "round_blocksize %d -> %d", blksize, rounded); | | 4624 | TRACE(1, "round_blocksize %d -> %d", blksize, rounded); |
4625 | if (rounded != blksize) { | | 4625 | if (rounded != blksize) { |
4626 | if ((rounded * NBBY) % (mixer->hwbuf.fmt.stride * | | 4626 | if ((rounded * NBBY) % (mixer->hwbuf.fmt.stride * |
4627 | mixer->hwbuf.fmt.channels) != 0) { | | 4627 | mixer->hwbuf.fmt.channels) != 0) { |
4628 | device_printf(sc->sc_dev, | | 4628 | device_printf(sc->sc_dev, |
4629 | "blksize not configured %d -> %d\n", | | 4629 | "blksize not configured %d -> %d\n", |
4630 | blksize, rounded); | | 4630 | blksize, rounded); |
4631 | return EINVAL; | | 4631 | return EINVAL; |
4632 | } | | 4632 | } |
4633 | /* Recalculation */ | | 4633 | /* Recalculation */ |
4634 | blksize = rounded; | | 4634 | blksize = rounded; |
4635 | mixer->frames_per_block = blksize * NBBY / | | 4635 | mixer->frames_per_block = blksize * NBBY / |
4636 | (mixer->hwbuf.fmt.stride * | | 4636 | (mixer->hwbuf.fmt.stride * |
4637 | mixer->hwbuf.fmt.channels); | | 4637 | mixer->hwbuf.fmt.channels); |
4638 | } | | 4638 | } |
4639 | } | | 4639 | } |
4640 | mixer->blktime_n = mixer->frames_per_block; | | 4640 | mixer->blktime_n = mixer->frames_per_block; |
4641 | mixer->blktime_d = mixer->hwbuf.fmt.sample_rate; | | 4641 | mixer->blktime_d = mixer->hwbuf.fmt.sample_rate; |
4642 | | | 4642 | |
4643 | capacity = mixer->frames_per_block * hwblks; | | 4643 | capacity = mixer->frames_per_block * hwblks; |
4644 | bufsize = frametobyte(&mixer->hwbuf.fmt, capacity); | | 4644 | bufsize = frametobyte(&mixer->hwbuf.fmt, capacity); |
4645 | if (sc->hw_if->round_buffersize) { | | 4645 | if (sc->hw_if->round_buffersize) { |
4646 | size_t rounded; | | 4646 | size_t rounded; |
4647 | rounded = sc->hw_if->round_buffersize(sc->hw_hdl, mode, | | 4647 | rounded = sc->hw_if->round_buffersize(sc->hw_hdl, mode, |
4648 | bufsize); | | 4648 | bufsize); |
4649 | TRACE(2, "round_buffersize %zd -> %zd", bufsize, rounded); | | 4649 | TRACE(1, "round_buffersize %zd -> %zd", bufsize, rounded); |
4650 | if (rounded < bufsize) { | | 4650 | if (rounded < bufsize) { |
4651 | /* buffersize needs NBLKHW blocks at least. */ | | 4651 | /* buffersize needs NBLKHW blocks at least. */ |
4652 | device_printf(sc->sc_dev, | | 4652 | device_printf(sc->sc_dev, |
4653 | "buffersize too small: buffersize=%zd blksize=%d\n", | | 4653 | "buffersize too small: buffersize=%zd blksize=%d\n", |
4654 | rounded, blksize); | | 4654 | rounded, blksize); |
4655 | return EINVAL; | | 4655 | return EINVAL; |
4656 | } | | 4656 | } |
4657 | if (rounded % blksize != 0) { | | 4657 | if (rounded % blksize != 0) { |
4658 | /* buffersize/blksize constraint mismatch? */ | | 4658 | /* buffersize/blksize constraint mismatch? */ |
4659 | device_printf(sc->sc_dev, | | 4659 | device_printf(sc->sc_dev, |
4660 | "buffersize must be multiple of blksize: " | | 4660 | "buffersize must be multiple of blksize: " |
4661 | "buffersize=%zu blksize=%d\n", | | 4661 | "buffersize=%zu blksize=%d\n", |
4662 | rounded, blksize); | | 4662 | rounded, blksize); |
4663 | return EINVAL; | | 4663 | return EINVAL; |
4664 | } | | 4664 | } |
4665 | if (rounded != bufsize) { | | 4665 | if (rounded != bufsize) { |
4666 | /* Recalcuration */ | | 4666 | /* Recalcuration */ |
4667 | bufsize = rounded; | | 4667 | bufsize = rounded; |
4668 | hwblks = bufsize / blksize; | | 4668 | hwblks = bufsize / blksize; |
4669 | capacity = mixer->frames_per_block * hwblks; | | 4669 | capacity = mixer->frames_per_block * hwblks; |
4670 | } | | 4670 | } |
4671 | } | | 4671 | } |
4672 | TRACE(2, "buffersize for %s = %zu", | | 4672 | TRACE(1, "buffersize for %s = %zu", |
4673 | (mode == AUMODE_PLAY) ? "playback" : "recording", | | 4673 | (mode == AUMODE_PLAY) ? "playback" : "recording", |
4674 | bufsize); | | 4674 | bufsize); |
4675 | mixer->hwbuf.capacity = capacity; | | 4675 | mixer->hwbuf.capacity = capacity; |
4676 | | | 4676 | |
4677 | /* | | 4677 | /* |
4678 | * XXX need to release sc_lock for compatibility? | | 4678 | * XXX need to release sc_lock for compatibility? |
4679 | */ | | 4679 | */ |
4680 | if (sc->hw_if->allocm) { | | 4680 | if (sc->hw_if->allocm) { |
4681 | mixer->hwbuf.mem = sc->hw_if->allocm(sc->hw_hdl, mode, bufsize); | | 4681 | mixer->hwbuf.mem = sc->hw_if->allocm(sc->hw_hdl, mode, bufsize); |
4682 | if (mixer->hwbuf.mem == NULL) { | | 4682 | if (mixer->hwbuf.mem == NULL) { |
4683 | device_printf(sc->sc_dev, "%s: allocm(%zu) failed\n", | | 4683 | device_printf(sc->sc_dev, "%s: allocm(%zu) failed\n", |
4684 | __func__, bufsize); | | 4684 | __func__, bufsize); |
4685 | return ENOMEM; | | 4685 | return ENOMEM; |