This patch is a differential patch from audio2-20190401.diff.gz. diff --git a/sys/dev/audio/audio.c b/sys/dev/audio/audio.c index 769f0cb72..bb81cc5ad 100644 --- a/sys/dev/audio/audio.c +++ b/sys/dev/audio/audio.c @@ -6495,7 +6498,7 @@ audio_hw_probe_by_encoding(struct audio_softc *sc, audio_format2_t *cand, KASSERT(mutex_owned(sc->sc_lock)); - fmt.encoding = AUDIO_ENCODING_SLINEAR_LE; + fmt.encoding = AUDIO_ENCODING_SLINEAR_NE; fmt.precision = AUDIO_INTERNAL_BITS; fmt.stride = AUDIO_INTERNAL_BITS; @@ -7408,14 +7411,16 @@ audio_hw_set_params(struct audio_softc *sc, int setmode, error = sc->hw_if->set_format(sc->hw_hdl, setmode, &pp, &rp, pfil, rfil); if (error) { - TRACE(1, "set_format failed with %d", error); + device_printf(sc->sc_dev, + "set_format failed with %d\n", error); return error; } } else { error = sc->hw_if->set_params(sc->hw_hdl, setmode, usemode, &pp, &rp, &pfilters, &rfilters); if (error) { - TRACE(1, "set_params failed with %d", error); + device_printf(sc->sc_dev, + "set_params failed with %d\n", error); return error; } } @@ -7423,7 +7428,8 @@ audio_hw_set_params(struct audio_softc *sc, int setmode, if (sc->hw_if->commit_settings) { error = sc->hw_if->commit_settings(sc->hw_hdl); if (error) { - TRACE(1, "commit_settings failed with %d", error); + device_printf(sc->sc_dev, + "commit_settings failed with %d\n", error); return error; } } diff --git a/sys/arch/arm/iomd/vidcaudio.c b/sys/arch/arm/iomd/vidcaudio.c index efff32058..dd0594706 100644 --- a/sys/arch/arm/iomd/vidcaudio.c +++ b/sys/arch/arm/iomd/vidcaudio.c @@ -79,8 +79,12 @@ __KERNEL_RCSID(0, "$NetBSD: vidcaudio.c,v 1.57 2019/03/16 12:09:56 isaki Exp $") #include #include +#if defined(AUDIO2) +#include +#else #include #include +#endif #include #include @@ -138,19 +142,28 @@ static int vidcaudio_intr(void *); static void vidcaudio_rate(int); static void vidcaudio_ctrl(int); static void vidcaudio_stereo(int, int); +#if !defined(AUDIO2) static stream_filter_factory_t mulaw_to_vidc; static stream_filter_factory_t mulaw_to_vidc_stereo; static int mulaw_to_vidc_fetch_to(struct audio_softc *, stream_fetcher_t *, audio_stream_t *, int); static int mulaw_to_vidc_stereo_fetch_to(struct audio_softc *, stream_fetcher_t *, audio_stream_t *, int); +#endif CFATTACH_DECL_NEW(vidcaudio, sizeof(struct vidcaudio_softc), vidcaudio_probe, vidcaudio_attach, NULL, NULL); +#if defined(AUDIO2) +static int vidcaudio_query_format(void *, audio_format_query_t *); +static int vidcaudio_set_format(void *, int, + const audio_params_t *, const audio_params_t *, + audio_filter_reg_t *, audio_filter_reg_t *); +#else static int vidcaudio_query_encoding(void *, struct audio_encoding *); static int vidcaudio_set_params(void *, int, int, audio_params_t *, audio_params_t *, stream_filter_list_t *, stream_filter_list_t *); +#endif static int vidcaudio_round_blocksize(void *, int, int, const audio_params_t *); static int vidcaudio_trigger_output(void *, void *, void *, int, void (*)(void *), void *, const audio_params_t *); @@ -173,8 +186,13 @@ static struct audio_device vidcaudio_device = { static const struct audio_hw_if vidcaudio_hw_if = { .close = vidcaudio_close, +#if defined(AUDIO2) + .query_format = vidcaudio_query_format, + .set_format = vidcaudio_set_format, +#else .query_encoding = vidcaudio_query_encoding, .set_params = vidcaudio_set_params, +#endif .round_blocksize = vidcaudio_round_blocksize, .halt_output = vidcaudio_halt_output, .halt_input = vidcaudio_halt_input, @@ -188,6 +206,45 @@ static const struct audio_hw_if vidcaudio_hw_if = { .get_locks = vidcaudio_get_locks, }; +#if defined(AUDIO2) +static const struct audio_format vidcaudio_formats_16bit = { + .mode = AUMODE_PLAY, + .encoding = AUDIO_ENCODING_SLINEAR_LE, + .validbits = 16, + .precision = 16, + .channels = 2, + .channel_mask = AUFMT_STEREO, + /* There are more selectable frequencies but these should be enough. */ + .frequency_type = 6, + .frequency = { + 19600, /* /9 */ + 22050, /* /8 */ + 25200, /* /7 */ + 29400, /* /6 */ + 35280, /* /5 */ + 44100, /* /4 */ + }, +}; +static const struct audio_format vidcaudio_formats_8bit = { + .mode = AUMODE_PLAY, + .encoding = AUDIO_ENCODING_ULAW, + .validbits = 8, + .precision = 8, + .channels = 2, /* we use stereo always */ + .channel_mask = AUFMT_STEREO, + /* frequency is preferably an integer. */ + .frequency_type = 6, + .frequency = { + 10000, /* 50us */ + 12500, /* 40us */ + 20000, /* 25us */ + 25000, /* 20us */ + 31250, /* 16us */ + 50000, /* 10us */ + }, +}; +#endif + static int vidcaudio_probe(device_t parent, cfdata_t cf, void *aux) { @@ -282,6 +339,59 @@ vidcaudio_close(void *addr) * Interface to the generic audio driver */ +#if defined(AUDIO2) +static int +vidcaudio_query_format(void *addr, audio_format_query_t *afp) +{ + struct vidcaudio_softc *sc; + + sc = addr; + if (sc->sc_is16bit) + return audio_query_format(&vidcaudio_formats_16bit, 1, afp); + else + return audio_query_format(&vidcaudio_formats_8bit, 1, afp); +} + +static int +vidcaudio_set_format(void *addr, int setmode, + const audio_params_t *play, const audio_params_t *rec, + audio_filter_reg_t *pfil, audio_filter_reg_t *rfil) +{ + struct vidcaudio_softc *sc; + int sample_period, ch; + + sc = addr; + if (sc->sc_is16bit) { + /* ARM7500ish, 16-bit, two-channel */ + sample_period = 705600 / 4 / play->sample_rate; + if (sample_period < 3) + sample_period = 3; + vidcaudio_rate(sample_period - 2); + vidcaudio_ctrl(SCR_SERIAL); + } else { + /* VIDC20ish, u-law, 8-channel */ + /* + * We always use two hardware channels, because using + * one at 8kHz gives a nasty whining sound from the + * speaker. + */ + sample_period = 1000000 / 2 / play->sample_rate; + if (sample_period < 3) + sample_period = 3; + vidcaudio_rate(sample_period - 2); + vidcaudio_ctrl(SCR_SDAC | SCR_CLKSEL); + for (ch = 0; ch < 8; ch += 2) + vidcaudio_stereo(ch, SIR_LEFT_100); + for (ch = 1; ch < 8; ch += 2) + vidcaudio_stereo(ch, SIR_RIGHT_100); + + pfil->codec = audio_internal_to_mulaw; + } + return 0; +} + +#else + static int vidcaudio_query_encoding(void *addr, struct audio_encoding *fp) { @@ -429,6 +539,7 @@ vidcaudio_set_params(void *addr, int setmode, int usemode, } return 0; } +#endif /* AUDIO2 */ static int vidcaudio_round_blocksize(void *addr, int wantblk, diff --git a/sys/arch/hppa/gsc/harmony.c b/sys/arch/hppa/gsc/harmony.c index faafd0d0b..26723c0ff 100644 --- a/sys/arch/hppa/gsc/harmony.c +++ b/sys/arch/hppa/gsc/harmony.c @@ -77,7 +77,9 @@ #include #include +#if !defined(AUDIO2) #include +#endif #include #include @@ -92,9 +94,16 @@ int harmony_open(void *, int); void harmony_close(void *); +#if defined(AUDIO2) +int harmony_query_format(void *, audio_format_query_t *); +int harmony_set_format(void *, int, + const audio_params_t *, const audio_params_t *, + audio_filter_reg_t *, audio_filter_reg_t *); +#else int harmony_query_encoding(void *, struct audio_encoding *); int harmony_set_params(void *, int, int, audio_params_t *, audio_params_t *, stream_filter_list_t *, stream_filter_list_t *); +#endif int harmony_round_blocksize(void *, int, int, const audio_params_t *); int harmony_control_wait(struct harmony_softc *); @@ -119,8 +128,13 @@ void harmony_get_locks(void *, kmutex_t **, kmutex_t **); const struct audio_hw_if harmony_sa_hw_if = { .open = harmony_open, .close = harmony_close, +#if defined(AUDIO2) + .query_format = harmony_query_format, + .set_format = harmony_set_format, +#else .query_encoding = harmony_query_encoding, .set_params = harmony_set_params, +#endif .round_blocksize = harmony_round_blocksize, .commit_settings = harmony_commit_settings, .halt_output = harmony_halt_output, @@ -138,6 +152,36 @@ const struct audio_hw_if harmony_sa_hw_if = { .get_locks = harmony_get_locks, }; +#if defined(AUDIO2) +#define HARMONY_FORMAT(enc, prec, ch, chmask) \ + { \ + .mode = AUMODE_PLAY | AUMODE_RECORD, \ + .encoding = (enc), \ + .validbits = (prec), \ + .precision = (prec), \ + .channels = (ch), \ + .channel_mask = (chmask), \ + .frequency_type = 14, \ + .frequency = { \ + 5125, 6615, 8000, 9600, 11025, 16000, 18900, \ + 22050, 27428, 32000, 33075, 37800, 44100, 48000, \ + }, \ + } +static struct audio_format harmony_formats[] = { + /* First two may be disabled at attach. */ + HARMONY_FORMAT(AUDIO_ENCODING_ULINEAR, 8, 1, AUFMT_MONAURAL), + HARMONY_FORMAT(AUDIO_ENCODING_ULINEAR, 8, 2, AUFMT_STEREO), + + HARMONY_FORMAT(AUDIO_ENCODING_ULAW, 8, 1, AUFMT_MONAURAL), + HARMONY_FORMAT(AUDIO_ENCODING_ULAW, 8, 2, AUFMT_STEREO), + HARMONY_FORMAT(AUDIO_ENCODING_ALAW, 8, 1, AUFMT_MONAURAL), + HARMONY_FORMAT(AUDIO_ENCODING_ALAW, 8, 2, AUFMT_STEREO), + HARMONY_FORMAT(AUDIO_ENCODING_SLINEAR_BE, 16, 1, AUFMT_MONAURAL), + HARMONY_FORMAT(AUDIO_ENCODING_SLINEAR_BE, 16, 2, AUFMT_STEREO), +}; +#define HARMONY_NFORMATS __arraycount(harmony_formats) +#endif + int harmony_match(device_t, struct cfdata *, void *); void harmony_attach(device_t, device_t, void *); @@ -300,6 +344,13 @@ harmony_attach(device_t parent, device_t self, void *aux) if ((rev & CS4215_REV_VER) >= CS4215_REV_VER_E) sc->sc_hasulinear8 = 1; +#if defined(AUDIO2) + /* XXX sc_hasulinear8 can be a local variable. */ + if (!sc->sc_hasulinear8) { + AUFMT_INVALIDATE(&harmony_formats[0]); + AUFMT_INVALIDATE(&harmony_formats[1]); + } +#endif strlcpy(sc->sc_audev.name, ga->ga_name, sizeof(sc->sc_audev.name)); snprintf(sc->sc_audev.version, sizeof sc->sc_audev.version, @@ -428,6 +479,63 @@ harmony_close(void *vsc) sc->sc_open = 0; } +#if defined(AUDIO2) +int +harmony_query_format(void *vsc, audio_format_query_t *afp) +{ + + return audio_query_format(harmony_formats, HARMONY_NFORMATS, afp); +} + +int +harmony_set_format(void *vsc, int setmode, + const audio_params_t *play, const audio_params_t *rec, + audio_filter_reg_t *pfil, audio_filter_reg_t *rfil) +{ + struct harmony_softc *sc; + uint32_t bits; + int rate; + + sc = vsc; + + /* *play and *rec are the identical because !AUDIO_PROP_INDEPENDENT. */ + switch (play->encoding) { + case AUDIO_ENCODING_ULAW: + bits = CNTL_FORMAT_ULAW; + break; + case AUDIO_ENCODING_ALAW: + bits = CNTL_FORMAT_ALAW; + break; + case AUDIO_ENCODING_SLINEAR_BE: + bits = CNTL_FORMAT_SLINEAR16BE; + break; + case AUDIO_ENCODING_ULINEAR: + bits = CNTL_FORMAT_ULINEAR8; + break; + default: + return EINVAL; + } + + if (sc->sc_outputgain) + bits |= CNTL_OLB; + + if (play->channels == 1) + bits |= CNTL_CHANS_MONO; + else if (play->channels == 2) + bits |= CNTL_CHANS_STEREO; + else + return EINVAL; + + /* XXX modify harmony_speed_bits() not to rewrite rate */ + rate = play->sample_rate; + sc->sc_cntlbits |= harmony_speed_bits(sc, &rate); + sc->sc_need_commit = 1; + + return 0; +} + +#else + int harmony_query_encoding(void *vsc, struct audio_encoding *fp) { @@ -608,6 +716,8 @@ harmony_set_params(void *vsc, int setmode, int usemode, return 0; } +#endif /* AUDIO2 */ + int harmony_round_blocksize(void *vsc, int blk, int mode, const audio_params_t *param)