| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: bcm2835_vcaudio.c,v 1.14 2019/05/08 13:40:14 isaki Exp $ */ | | 1 | /* $NetBSD: bcm2835_vcaudio.c,v 1.14.2.1 2021/01/25 14:14:23 martin Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2013 Jared D. McNeill <jmcneill@invisible.ca> | | 4 | * Copyright (c) 2013 Jared D. McNeill <jmcneill@invisible.ca> |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -21,27 +21,27 @@ | | | @@ -21,27 +21,27 @@ |
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
26 | * POSSIBILITY OF SUCH DAMAGE. | | 26 | * POSSIBILITY OF SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | /* | | 29 | /* |
30 | * VideoCore audio interface | | 30 | * VideoCore audio interface |
31 | */ | | 31 | */ |
32 | | | 32 | |
33 | #include <sys/cdefs.h> | | 33 | #include <sys/cdefs.h> |
34 | __KERNEL_RCSID(0, "$NetBSD: bcm2835_vcaudio.c,v 1.14 2019/05/08 13:40:14 isaki Exp $"); | | 34 | __KERNEL_RCSID(0, "$NetBSD: bcm2835_vcaudio.c,v 1.14.2.1 2021/01/25 14:14:23 martin Exp $"); |
35 | | | 35 | |
36 | #include <sys/param.h> | | 36 | #include <sys/param.h> |
37 | #include <sys/types.h> | | 37 | #include <sys/types.h> |
38 | #include <sys/systm.h> | | 38 | #include <sys/systm.h> |
39 | #include <sys/device.h> | | 39 | #include <sys/device.h> |
40 | #include <sys/conf.h> | | 40 | #include <sys/conf.h> |
41 | #include <sys/bus.h> | | 41 | #include <sys/bus.h> |
42 | #include <sys/kmem.h> | | 42 | #include <sys/kmem.h> |
43 | | | 43 | |
44 | #include <sys/audioio.h> | | 44 | #include <sys/audioio.h> |
45 | #include <dev/audio/audio_if.h> | | 45 | #include <dev/audio/audio_if.h> |
46 | | | 46 | |
47 | #include <interface/compat/vchi_bsd.h> | | 47 | #include <interface/compat/vchi_bsd.h> |
| @@ -149,58 +149,53 @@ static void vcaudio_childdet(device_t, d | | | @@ -149,58 +149,53 @@ static void vcaudio_childdet(device_t, d |
149 | | | 149 | |
150 | static int vcaudio_init(struct vcaudio_softc *); | | 150 | static int vcaudio_init(struct vcaudio_softc *); |
151 | static void vcaudio_service_callback(void *, | | 151 | static void vcaudio_service_callback(void *, |
152 | const VCHI_CALLBACK_REASON_T, void *); | | 152 | const VCHI_CALLBACK_REASON_T, void *); |
153 | static int vcaudio_msg_sync(struct vcaudio_softc *, VC_AUDIO_MSG_T *, | | 153 | static int vcaudio_msg_sync(struct vcaudio_softc *, VC_AUDIO_MSG_T *, |
154 | size_t); | | 154 | size_t); |
155 | static void vcaudio_worker(void *); | | 155 | static void vcaudio_worker(void *); |
156 | | | 156 | |
157 | static int vcaudio_query_format(void *, audio_format_query_t *); | | 157 | static int vcaudio_query_format(void *, audio_format_query_t *); |
158 | static int vcaudio_set_format(void *, int, | | 158 | static int vcaudio_set_format(void *, int, |
159 | const audio_params_t *, const audio_params_t *, | | 159 | const audio_params_t *, const audio_params_t *, |
160 | audio_filter_reg_t *, audio_filter_reg_t *); | | 160 | audio_filter_reg_t *, audio_filter_reg_t *); |
161 | static int vcaudio_halt_output(void *); | | 161 | static int vcaudio_halt_output(void *); |
162 | static int vcaudio_halt_input(void *); | | | |
163 | static int vcaudio_set_port(void *, mixer_ctrl_t *); | | 162 | static int vcaudio_set_port(void *, mixer_ctrl_t *); |
164 | static int vcaudio_get_port(void *, mixer_ctrl_t *); | | 163 | static int vcaudio_get_port(void *, mixer_ctrl_t *); |
165 | static int vcaudio_query_devinfo(void *, mixer_devinfo_t *); | | 164 | static int vcaudio_query_devinfo(void *, mixer_devinfo_t *); |
166 | static int vcaudio_getdev(void *, struct audio_device *); | | 165 | static int vcaudio_getdev(void *, struct audio_device *); |
167 | static int vcaudio_get_props(void *); | | 166 | static int vcaudio_get_props(void *); |
168 | | | 167 | |
169 | static int vcaudio_round_blocksize(void *, int, int, | | 168 | static int vcaudio_round_blocksize(void *, int, int, |
170 | const audio_params_t *); | | 169 | const audio_params_t *); |
171 | | | 170 | |
172 | static int vcaudio_trigger_output(void *, void *, void *, int, | | 171 | static int vcaudio_trigger_output(void *, void *, void *, int, |
173 | void (*)(void *), void *, const audio_params_t *); | | 172 | void (*)(void *), void *, const audio_params_t *); |
174 | static int vcaudio_trigger_input(void *, void *, void *, int, | | | |
175 | void (*)(void *), void *, const audio_params_t *); | | | |
176 | | | 173 | |
177 | static void vcaudio_get_locks(void *, kmutex_t **, kmutex_t **); | | 174 | static void vcaudio_get_locks(void *, kmutex_t **, kmutex_t **); |
178 | | | 175 | |
179 | static void vcaudio_swvol_codec(audio_filter_arg_t *); | | 176 | static void vcaudio_swvol_codec(audio_filter_arg_t *); |
180 | | | 177 | |
181 | static const struct audio_hw_if vcaudio_hw_if = { | | 178 | static const struct audio_hw_if vcaudio_hw_if = { |
182 | .query_format = vcaudio_query_format, | | 179 | .query_format = vcaudio_query_format, |
183 | .set_format = vcaudio_set_format, | | 180 | .set_format = vcaudio_set_format, |
184 | .halt_output = vcaudio_halt_output, | | 181 | .halt_output = vcaudio_halt_output, |
185 | .halt_input = vcaudio_halt_input, | | | |
186 | .getdev = vcaudio_getdev, | | 182 | .getdev = vcaudio_getdev, |
187 | .set_port = vcaudio_set_port, | | 183 | .set_port = vcaudio_set_port, |
188 | .get_port = vcaudio_get_port, | | 184 | .get_port = vcaudio_get_port, |
189 | .query_devinfo = vcaudio_query_devinfo, | | 185 | .query_devinfo = vcaudio_query_devinfo, |
190 | .get_props = vcaudio_get_props, | | 186 | .get_props = vcaudio_get_props, |
191 | .round_blocksize = vcaudio_round_blocksize, | | 187 | .round_blocksize = vcaudio_round_blocksize, |
192 | .trigger_output = vcaudio_trigger_output, | | 188 | .trigger_output = vcaudio_trigger_output, |
193 | .trigger_input = vcaudio_trigger_input, | | | |
194 | .get_locks = vcaudio_get_locks, | | 189 | .get_locks = vcaudio_get_locks, |
195 | }; | | 190 | }; |
196 | | | 191 | |
197 | CFATTACH_DECL2_NEW(vcaudio, sizeof(struct vcaudio_softc), | | 192 | CFATTACH_DECL2_NEW(vcaudio, sizeof(struct vcaudio_softc), |
198 | vcaudio_match, vcaudio_attach, NULL, NULL, vcaudio_rescan, | | 193 | vcaudio_match, vcaudio_attach, NULL, NULL, vcaudio_rescan, |
199 | vcaudio_childdet); | | 194 | vcaudio_childdet); |
200 | | | 195 | |
201 | static int | | 196 | static int |
202 | vcaudio_match(device_t parent, cfdata_t match, void *aux) | | 197 | vcaudio_match(device_t parent, cfdata_t match, void *aux) |
203 | { | | 198 | { |
204 | struct vchiq_attach_args *vaa = aux; | | 199 | struct vchiq_attach_args *vaa = aux; |
205 | | | 200 | |
206 | return !strcmp(vaa->vaa_name, "AUDS"); | | 201 | return !strcmp(vaa->vaa_name, "AUDS"); |
| @@ -605,32 +600,26 @@ vcaudio_halt_output(void *priv) | | | @@ -605,32 +600,26 @@ vcaudio_halt_output(void *priv) |
605 | | | 600 | |
606 | sc->sc_pint = NULL; | | 601 | sc->sc_pint = NULL; |
607 | sc->sc_pintarg = NULL; | | 602 | sc->sc_pintarg = NULL; |
608 | sc->sc_started = false; | | 603 | sc->sc_started = false; |
609 | | | 604 | |
610 | #ifdef VCAUDIO_DEBUG | | 605 | #ifdef VCAUDIO_DEBUG |
611 | device_printf(sc->sc_dev, "halting output\n"); | | 606 | device_printf(sc->sc_dev, "halting output\n"); |
612 | #endif | | 607 | #endif |
613 | | | 608 | |
614 | return error; | | 609 | return error; |
615 | } | | 610 | } |
616 | | | 611 | |
617 | static int | | 612 | static int |
618 | vcaudio_halt_input(void *priv) | | | |
619 | { | | | |
620 | return EINVAL; | | | |
621 | } | | | |
622 | | | | |
623 | static int | | | |
624 | vcaudio_set_volume(struct vcaudio_softc *sc, enum vcaudio_dest dest, | | 613 | vcaudio_set_volume(struct vcaudio_softc *sc, enum vcaudio_dest dest, |
625 | int hwvol) | | 614 | int hwvol) |
626 | { | | 615 | { |
627 | VC_AUDIO_MSG_T msg; | | 616 | VC_AUDIO_MSG_T msg; |
628 | int error; | | 617 | int error; |
629 | | | 618 | |
630 | sc->sc_hwvol[dest] = hwvol; | | 619 | sc->sc_hwvol[dest] = hwvol; |
631 | if (dest != sc->sc_dest) | | 620 | if (dest != sc->sc_dest) |
632 | return 0; | | 621 | return 0; |
633 | | | 622 | |
634 | vchi_service_use(sc->sc_service); | | 623 | vchi_service_use(sc->sc_service); |
635 | | | 624 | |
636 | memset(&msg, 0, sizeof(msg)); | | 625 | memset(&msg, 0, sizeof(msg)); |
| @@ -795,27 +784,27 @@ vcaudio_getdev(void *priv, struct audio_ | | | @@ -795,27 +784,27 @@ vcaudio_getdev(void *priv, struct audio_ |
795 | struct vcaudio_softc *sc = priv; | | 784 | struct vcaudio_softc *sc = priv; |
796 | | | 785 | |
797 | snprintf(audiodev->name, sizeof(audiodev->name), "vchiq auds"); | | 786 | snprintf(audiodev->name, sizeof(audiodev->name), "vchiq auds"); |
798 | snprintf(audiodev->version, sizeof(audiodev->version), | | 787 | snprintf(audiodev->version, sizeof(audiodev->version), |
799 | "%d", sc->sc_peer_version); | | 788 | "%d", sc->sc_peer_version); |
800 | snprintf(audiodev->config, sizeof(audiodev->config), "vcaudio"); | | 789 | snprintf(audiodev->config, sizeof(audiodev->config), "vcaudio"); |
801 | | | 790 | |
802 | return 0; | | 791 | return 0; |
803 | } | | 792 | } |
804 | | | 793 | |
805 | static int | | 794 | static int |
806 | vcaudio_get_props(void *priv) | | 795 | vcaudio_get_props(void *priv) |
807 | { | | 796 | { |
808 | return AUDIO_PROP_PLAYBACK|AUDIO_PROP_CAPTURE|AUDIO_PROP_INDEPENDENT; | | 797 | return AUDIO_PROP_PLAYBACK; |
809 | } | | 798 | } |
810 | | | 799 | |
811 | static int | | 800 | static int |
812 | vcaudio_round_blocksize(void *priv, int bs, int mode, | | 801 | vcaudio_round_blocksize(void *priv, int bs, int mode, |
813 | const audio_params_t *params) | | 802 | const audio_params_t *params) |
814 | { | | 803 | { |
815 | return VCAUDIO_BLOCKSIZE; | | 804 | return VCAUDIO_BLOCKSIZE; |
816 | } | | 805 | } |
817 | | | 806 | |
818 | static int | | 807 | static int |
819 | vcaudio_trigger_output(void *priv, void *start, void *end, int blksize, | | 808 | vcaudio_trigger_output(void *priv, void *start, void *end, int blksize, |
820 | void (*intr)(void *), void *intrarg, const audio_params_t *params) | | 809 | void (*intr)(void *), void *intrarg, const audio_params_t *params) |
821 | { | | 810 | { |
| @@ -830,33 +819,26 @@ vcaudio_trigger_output(void *priv, void | | | @@ -830,33 +819,26 @@ vcaudio_trigger_output(void *priv, void |
830 | sc->sc_ppos = 0; | | 819 | sc->sc_ppos = 0; |
831 | sc->sc_pstart = start; | | 820 | sc->sc_pstart = start; |
832 | sc->sc_pend = end; | | 821 | sc->sc_pend = end; |
833 | sc->sc_pblksize = blksize; | | 822 | sc->sc_pblksize = blksize; |
834 | sc->sc_pblkcnt = 0; | | 823 | sc->sc_pblkcnt = 0; |
835 | sc->sc_pbytes = 0; | | 824 | sc->sc_pbytes = 0; |
836 | sc->sc_abytes = blksize; | | 825 | sc->sc_abytes = blksize; |
837 | | | 826 | |
838 | cv_signal(&sc->sc_datacv); | | 827 | cv_signal(&sc->sc_datacv); |
839 | | | 828 | |
840 | return 0; | | 829 | return 0; |
841 | } | | 830 | } |
842 | | | 831 | |
843 | static int | | | |
844 | vcaudio_trigger_input(void *priv, void *start, void *end, int blksize, | | | |
845 | void (*intr)(void *), void *intrarg, const audio_params_t *params) | | | |
846 | { | | | |
847 | return EINVAL; | | | |
848 | } | | | |
849 | | | | |
850 | static void | | 832 | static void |
851 | vcaudio_get_locks(void *priv, kmutex_t **intr, kmutex_t **thread) | | 833 | vcaudio_get_locks(void *priv, kmutex_t **intr, kmutex_t **thread) |
852 | { | | 834 | { |
853 | struct vcaudio_softc *sc = priv; | | 835 | struct vcaudio_softc *sc = priv; |
854 | | | 836 | |
855 | *intr = &sc->sc_intr_lock; | | 837 | *intr = &sc->sc_intr_lock; |
856 | *thread = &sc->sc_lock; | | 838 | *thread = &sc->sc_lock; |
857 | } | | 839 | } |
858 | | | 840 | |
859 | static void | | 841 | static void |
860 | vcaudio_swvol_codec(audio_filter_arg_t *arg) | | 842 | vcaudio_swvol_codec(audio_filter_arg_t *arg) |
861 | { | | 843 | { |
862 | struct vcaudio_softc *sc = arg->context; | | 844 | struct vcaudio_softc *sc = arg->context; |