| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: vs.c,v 1.47 2017/09/02 12:52:55 isaki Exp $ */ | | 1 | /* $NetBSD: vs.c,v 1.48 2017/09/02 15:40:31 isaki Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2001 Tetsuya Isaki. All rights reserved. | | 4 | * Copyright (c) 2001 Tetsuya Isaki. All rights reserved. |
5 | * | | 5 | * |
6 | * Redistribution and use in source and binary forms, with or without | | 6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions | | 7 | * modification, are permitted provided that the following conditions |
8 | * are met: | | 8 | * are met: |
9 | * 1. Redistributions of source code must retain the above copyright | | 9 | * 1. Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. | | 10 | * notice, this list of conditions and the following disclaimer. |
11 | * 2. Redistributions in binary form must reproduce the above copyright | | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
12 | * notice, this list of conditions and the following disclaimer in the | | 12 | * notice, this list of conditions and the following disclaimer in the |
13 | * documentation and/or other materials provided with the distribution. | | 13 | * documentation and/or other materials provided with the distribution. |
14 | * | | 14 | * |
| @@ -20,27 +20,27 @@ | | | @@ -20,27 +20,27 @@ |
20 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | | 20 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | | 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
22 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | | 22 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
23 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 23 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
24 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 24 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
25 | * SUCH DAMAGE. | | 25 | * SUCH DAMAGE. |
26 | */ | | 26 | */ |
27 | | | 27 | |
28 | /* | | 28 | /* |
29 | * VS - OKI MSM6258 ADPCM voice synthesizer device driver. | | 29 | * VS - OKI MSM6258 ADPCM voice synthesizer device driver. |
30 | */ | | 30 | */ |
31 | | | 31 | |
32 | #include <sys/cdefs.h> | | 32 | #include <sys/cdefs.h> |
33 | __KERNEL_RCSID(0, "$NetBSD: vs.c,v 1.47 2017/09/02 12:52:55 isaki Exp $"); | | 33 | __KERNEL_RCSID(0, "$NetBSD: vs.c,v 1.48 2017/09/02 15:40:31 isaki Exp $"); |
34 | | | 34 | |
35 | #include "audio.h" | | 35 | #include "audio.h" |
36 | #include "vs.h" | | 36 | #include "vs.h" |
37 | #if NAUDIO > 0 && NVS > 0 | | 37 | #if NAUDIO > 0 && NVS > 0 |
38 | | | 38 | |
39 | #include <sys/param.h> | | 39 | #include <sys/param.h> |
40 | #include <sys/systm.h> | | 40 | #include <sys/systm.h> |
41 | #include <sys/device.h> | | 41 | #include <sys/device.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_if.h> | | 45 | #include <dev/audio_if.h> |
46 | #include <dev/mulaw.h> | | 46 | #include <dev/mulaw.h> |
| @@ -150,28 +150,26 @@ struct { | | | @@ -150,28 +150,26 @@ struct { |
150 | u_long rate; | | 150 | u_long rate; |
151 | u_char clk; | | 151 | u_char clk; |
152 | u_char den; | | 152 | u_char den; |
153 | } vs_l2r[] = { | | 153 | } vs_l2r[] = { |
154 | { VS_RATE_15K, VS_CLK_8MHZ, VS_SRATE_512 }, | | 154 | { VS_RATE_15K, VS_CLK_8MHZ, VS_SRATE_512 }, |
155 | { VS_RATE_10K, VS_CLK_8MHZ, VS_SRATE_768 }, | | 155 | { VS_RATE_10K, VS_CLK_8MHZ, VS_SRATE_768 }, |
156 | { VS_RATE_7K, VS_CLK_8MHZ, VS_SRATE_1024}, | | 156 | { VS_RATE_7K, VS_CLK_8MHZ, VS_SRATE_1024}, |
157 | { VS_RATE_5K, VS_CLK_4MHZ, VS_SRATE_768 }, | | 157 | { VS_RATE_5K, VS_CLK_4MHZ, VS_SRATE_768 }, |
158 | { VS_RATE_3K, VS_CLK_4MHZ, VS_SRATE_1024} | | 158 | { VS_RATE_3K, VS_CLK_4MHZ, VS_SRATE_1024} |
159 | }; | | 159 | }; |
160 | | | 160 | |
161 | #define NUM_RATE (sizeof(vs_l2r)/sizeof(vs_l2r[0])) | | 161 | #define NUM_RATE (sizeof(vs_l2r)/sizeof(vs_l2r[0])) |
162 | | | 162 | |
163 | extern stream_filter_factory_t null_filter; | | | |
164 | | | | |
165 | static int | | 163 | static int |
166 | vs_match(device_t parent, cfdata_t cf, void *aux) | | 164 | vs_match(device_t parent, cfdata_t cf, void *aux) |
167 | { | | 165 | { |
168 | struct intio_attach_args *ia; | | 166 | struct intio_attach_args *ia; |
169 | | | 167 | |
170 | ia = aux; | | 168 | ia = aux; |
171 | if (strcmp(ia->ia_name, "vs") || vs_attached) | | 169 | if (strcmp(ia->ia_name, "vs") || vs_attached) |
172 | return 0; | | 170 | return 0; |
173 | | | 171 | |
174 | if (ia->ia_addr == INTIOCF_ADDR_DEFAULT) | | 172 | if (ia->ia_addr == INTIOCF_ADDR_DEFAULT) |
175 | ia->ia_addr = VS_ADDR; | | 173 | ia->ia_addr = VS_ADDR; |
176 | if (ia->ia_dma == INTIOCF_DMA_DEFAULT) | | 174 | if (ia->ia_dma == INTIOCF_DMA_DEFAULT) |
177 | ia->ia_dma = VS_DMA; | | 175 | ia->ia_dma = VS_DMA; |
| @@ -355,26 +353,27 @@ vs_round_sr(u_long rate) | | | @@ -355,26 +353,27 @@ vs_round_sr(u_long rate) |
355 | } | | 353 | } |
356 | if (diff * 100 / rate > 15) | | 354 | if (diff * 100 / rate > 15) |
357 | return -1; | | 355 | return -1; |
358 | else | | 356 | else |
359 | return nearest; | | 357 | return nearest; |
360 | } | | 358 | } |
361 | | | 359 | |
362 | static int | | 360 | static int |
363 | vs_set_params(void *hdl, int setmode, int usemode, | | 361 | vs_set_params(void *hdl, int setmode, int usemode, |
364 | audio_params_t *play, audio_params_t *rec, | | 362 | audio_params_t *play, audio_params_t *rec, |
365 | stream_filter_list_t *pfil, stream_filter_list_t *rfil) | | 363 | stream_filter_list_t *pfil, stream_filter_list_t *rfil) |
366 | { | | 364 | { |
367 | struct vs_softc *sc; | | 365 | struct vs_softc *sc; |
| | | 366 | audio_params_t hw; |
368 | stream_filter_factory_t *pconv; | | 367 | stream_filter_factory_t *pconv; |
369 | stream_filter_factory_t *rconv; | | 368 | stream_filter_factory_t *rconv; |
370 | int rate; | | 369 | int rate; |
371 | | | 370 | |
372 | sc = hdl; | | 371 | sc = hdl; |
373 | | | 372 | |
374 | DPRINTF(1, ("vs_set_params: mode=%d enc=%d rate=%d prec=%d ch=%d: ", | | 373 | DPRINTF(1, ("vs_set_params: mode=%d enc=%d rate=%d prec=%d ch=%d: ", |
375 | setmode, play->encoding, play->sample_rate, | | 374 | setmode, play->encoding, play->sample_rate, |
376 | play->precision, play->channels)); | | 375 | play->precision, play->channels)); |
377 | | | 376 | |
378 | /* *play and *rec are identical because !AUDIO_PROP_INDEPENDENT */ | | 377 | /* *play and *rec are identical because !AUDIO_PROP_INDEPENDENT */ |
379 | | | 378 | |
380 | if (play->channels != 1) { | | 379 | if (play->channels != 1) { |
| @@ -395,38 +394,38 @@ vs_set_params(void *hdl, int setmode, in | | | @@ -395,38 +394,38 @@ vs_set_params(void *hdl, int setmode, in |
395 | play->encoding == AUDIO_ENCODING_SLINEAR_BE) { | | 394 | play->encoding == AUDIO_ENCODING_SLINEAR_BE) { |
396 | pconv = msm6258_slinear16_to_adpcm; | | 395 | pconv = msm6258_slinear16_to_adpcm; |
397 | rconv = msm6258_adpcm_to_slinear16; | | 396 | rconv = msm6258_adpcm_to_slinear16; |
398 | } else { | | 397 | } else { |
399 | DPRINTF(1, ("prec/enc not matched\n")); | | 398 | DPRINTF(1, ("prec/enc not matched\n")); |
400 | return EINVAL; | | 399 | return EINVAL; |
401 | } | | 400 | } |
402 | | | 401 | |
403 | sc->sc_current.rate = rate; | | 402 | sc->sc_current.rate = rate; |
404 | | | 403 | |
405 | /* pfil and rfil are independent even if !AUDIO_PROP_INDEPENDENT */ | | 404 | /* pfil and rfil are independent even if !AUDIO_PROP_INDEPENDENT */ |
406 | | | 405 | |
407 | if ((setmode & AUMODE_PLAY) != 0) { | | 406 | if ((setmode & AUMODE_PLAY) != 0) { |
408 | pfil->append(pfil, null_filter, play); | | 407 | hw = *play; |
409 | play->encoding = AUDIO_ENCODING_ADPCM; | | 408 | hw.encoding = AUDIO_ENCODING_ADPCM; |
410 | play->validbits = 4; | | 409 | hw.precision = 4; |
411 | play->precision = 4; | | 410 | hw.validbits = 4; |
412 | pfil->append(pfil, pconv, play); | | 411 | pfil->prepend(pfil, pconv, &hw); |
413 | } | | 412 | } |
414 | if ((setmode & AUMODE_RECORD) != 0) { | | 413 | if ((setmode & AUMODE_RECORD) != 0) { |
415 | rfil->append(rfil, null_filter, rec); | | 414 | hw = *rec; |
416 | rec->encoding = AUDIO_ENCODING_ADPCM; | | 415 | hw.encoding = AUDIO_ENCODING_ADPCM; |
417 | rec->validbits = 4; | | 416 | hw.precision = 4; |
418 | rec->precision = 4; | | 417 | hw.validbits = 4; |
419 | rfil->append(rfil, rconv, rec); | | 418 | rfil->prepend(rfil, rconv, &hw); |
420 | } | | 419 | } |
421 | | | 420 | |
422 | DPRINTF(1, ("accepted\n")); | | 421 | DPRINTF(1, ("accepted\n")); |
423 | return 0; | | 422 | return 0; |
424 | } | | 423 | } |
425 | | | 424 | |
426 | static void | | 425 | static void |
427 | vs_set_sr(struct vs_softc *sc, int rate) | | 426 | vs_set_sr(struct vs_softc *sc, int rate) |
428 | { | | 427 | { |
429 | | | 428 | |
430 | DPRINTF(1, ("setting sample rate to %d, %d\n", | | 429 | DPRINTF(1, ("setting sample rate to %d, %d\n", |
431 | rate, (int)vs_l2r[rate].rate)); | | 430 | rate, (int)vs_l2r[rate].rate)); |
432 | bus_space_write_1(sc->sc_iot, sc->sc_ppi, PPI_PORTC, | | 431 | bus_space_write_1(sc->sc_iot, sc->sc_ppi, PPI_PORTC, |