Module Name: src Committed By: isaki Date: Sun Apr 28 07:48:15 UTC 2019
Modified Files: src/sys/dev/pci [isaki-audio2]: neo.c Log Message: Adapt to audio2. - XXX In audio2, number of blocks must be 3 or greater, so modify round_blocksize() to return bufsize / 4. - XXX Doesn't neo_trigger_input() need to subtract ssz from buffer end like trigger_output()? To generate a diff of this commit: cvs rdiff -u -r1.52.2.1 -r1.52.2.2 src/sys/dev/pci/neo.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/neo.c diff -u src/sys/dev/pci/neo.c:1.52.2.1 src/sys/dev/pci/neo.c:1.52.2.2 --- src/sys/dev/pci/neo.c:1.52.2.1 Sun Apr 21 05:11:22 2019 +++ src/sys/dev/pci/neo.c Sun Apr 28 07:48:15 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: neo.c,v 1.52.2.1 2019/04/21 05:11:22 isaki Exp $ */ +/* $NetBSD: neo.c,v 1.52.2.2 2019/04/28 07:48:15 isaki Exp $ */ /* * Copyright (c) 1999 Cameron Grant <gand...@vilnya.demon.co.uk> @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: neo.c,v 1.52.2.1 2019/04/21 05:11:22 isaki Exp $"); +__KERNEL_RCSID(0, "$NetBSD: neo.c,v 1.52.2.2 2019/04/28 07:48:15 isaki Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -43,8 +43,6 @@ __KERNEL_RCSID(0, "$NetBSD: neo.c,v 1.52 #include <sys/audioio.h> #include <dev/audio_if.h> -#include <dev/mulaw.h> -#include <dev/auconv.h> #include <dev/ic/ac97var.h> @@ -176,11 +174,12 @@ static int nm_init(struct neo_softc *); static int neo_match(device_t, cfdata_t, void *); static void neo_attach(device_t, device_t, void *); static int neo_intr(void *); +static int neo_rate2index(u_int); -static int neo_query_encoding(void *, struct audio_encoding *); -static int neo_set_params(void *, int, int, audio_params_t *, - audio_params_t *, stream_filter_list_t *, - stream_filter_list_t *); +static int neo_query_format(void *, audio_format_query_t *); +static int neo_set_format(void *, int, + const audio_params_t *, const audio_params_t *, + audio_filter_reg_t *, audio_filter_reg_t *); static int neo_round_blocksize(void *, int, int, const audio_params_t *); static int neo_trigger_output(void *, void *, void *, int, void (*)(void *), void *, @@ -202,7 +201,6 @@ static int neo_query_devinfo(void *, mix static void * neo_malloc(void *, int, size_t); static void neo_free(void *, void *, size_t); static size_t neo_round_buffersize(void *, int, size_t); -static paddr_t neo_mappage(void *, void *, off_t, int); static int neo_get_props(void *); static void neo_get_locks(void *, kmutex_t **, kmutex_t **); @@ -215,44 +213,30 @@ static struct audio_device neo_device = "neo" }; -/* The actual rates supported by the card. */ -static const int samplerates[9] = { - 8000, - 11025, - 16000, - 22050, - 24000, - 32000, - 44100, - 48000, - 99999999 -}; - -#define NEO_NFORMATS 4 -#define NEO_FORMAT(enc, prec, ch, chmask) \ - { \ - .mode = AUMODE_PLAY | AUMODE_RECORD, \ - .encoding = (enc), \ - .validbits = (prec), \ - .precision = (prec), \ - .channels = (ch), \ - .channel_mask = (chmask), \ - .frequency_type = 8, \ - .frequency = \ - { 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000 }, \ - } -static const struct audio_format neo_formats[NEO_NFORMATS] = { - NEO_FORMAT(AUDIO_ENCODING_SLINEAR_LE, 16, 2, AUFMT_STEREO), - NEO_FORMAT(AUDIO_ENCODING_SLINEAR_LE, 16, 1, AUFMT_MONAURAL), - NEO_FORMAT(AUDIO_ENCODING_ULINEAR_LE, 8, 2, AUFMT_STEREO), - NEO_FORMAT(AUDIO_ENCODING_ULINEAR_LE, 8, 1, AUFMT_MONAURAL), +/* + * The frequency list in this format is also referred from neo_rate2index(). + * So don't rearrange or delete entries. + */ +static const struct audio_format neo_formats[] = { + { + .mode = AUMODE_PLAY | AUMODE_RECORD, + .encoding = AUDIO_ENCODING_SLINEAR_LE, + .validbits = 16, + .precision = 16, + .channels = 2, + .channel_mask = AUFMT_STEREO, + .frequency_type = 8, + .frequency = + { 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000 }, + }, }; +#define NEO_NFORMATS __arraycount(neo_formats) /* -------------------------------------------------------------------- */ static const struct audio_hw_if neo_hw_if = { - .query_encoding = neo_query_encoding, - .set_params = neo_set_params, + .query_format = neo_query_format, + .set_format = neo_set_format, .round_blocksize = neo_round_blocksize, .halt_output = neo_halt_output, .halt_input = neo_halt_input, @@ -263,7 +247,6 @@ static const struct audio_hw_if neo_hw_i .allocm = neo_malloc, .freem = neo_free, .round_buffersize = neo_round_buffersize, - .mappage = neo_mappage, .get_props = neo_get_props, .trigger_output = neo_trigger_output, .trigger_input = neo_trigger_input, @@ -722,75 +705,38 @@ neo_flags_codec(void *v) } static int -neo_query_encoding(void *addr, struct audio_encoding *fp) +neo_query_format(void *addr, audio_format_query_t *afp) { - switch (fp->index) { - case 0: - strcpy(fp->name, AudioEulinear); - fp->encoding = AUDIO_ENCODING_ULINEAR; - fp->precision = 8; - fp->flags = 0; - return 0; - case 1: - strcpy(fp->name, AudioEmulaw); - fp->encoding = AUDIO_ENCODING_ULAW; - fp->precision = 8; - fp->flags = AUDIO_ENCODINGFLAG_EMULATED; - return 0; - case 2: - strcpy(fp->name, AudioEalaw); - fp->encoding = AUDIO_ENCODING_ALAW; - fp->precision = 8; - fp->flags = AUDIO_ENCODINGFLAG_EMULATED; - return 0; - case 3: - strcpy(fp->name, AudioEslinear); - fp->encoding = AUDIO_ENCODING_SLINEAR; - fp->precision = 8; - fp->flags = AUDIO_ENCODINGFLAG_EMULATED; - return (0); - case 4: - strcpy(fp->name, AudioEslinear_le); - fp->encoding = AUDIO_ENCODING_SLINEAR_LE; - fp->precision = 16; - fp->flags = 0; - return 0; - case 5: - strcpy(fp->name, AudioEulinear_le); - fp->encoding = AUDIO_ENCODING_ULINEAR_LE; - fp->precision = 16; - fp->flags = AUDIO_ENCODINGFLAG_EMULATED; - return 0; - case 6: - strcpy(fp->name, AudioEslinear_be); - fp->encoding = AUDIO_ENCODING_SLINEAR_BE; - fp->precision = 16; - fp->flags = AUDIO_ENCODINGFLAG_EMULATED; - return 0; - case 7: - strcpy(fp->name, AudioEulinear_be); - fp->encoding = AUDIO_ENCODING_ULINEAR_BE; - fp->precision = 16; - fp->flags = AUDIO_ENCODINGFLAG_EMULATED; - return 0; - default: - return EINVAL; + return audio_query_format(neo_formats, NEO_NFORMATS, afp); +} + +/* Return index number of sample_rate */ +static int +neo_rate2index(u_int sample_rate) +{ + int i; + + for (i = 0; i < neo_formats[0].frequency_type; i++) { + if (sample_rate == neo_formats[0].frequency[i]) + return i; } + + /* NOTREACHED */ + panic("neo_formats.frequency mismatch?"); } /* Todo: don't commit settings to card until we've verified all parameters */ static int -neo_set_params(void *addr, int setmode, int usemode, - audio_params_t *play, audio_params_t *rec, stream_filter_list_t *pfil, - stream_filter_list_t *rfil) +neo_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 neo_softc *sc; - audio_params_t *p; - stream_filter_list_t *fil; + const audio_params_t *p; uint32_t base; uint8_t x; - int mode, i; + int mode; sc = addr; for (mode = AUMODE_RECORD; mode != -1; @@ -800,35 +746,17 @@ neo_set_params(void *addr, int setmode, p = mode == AUMODE_PLAY ? play : rec; - if (p == NULL) continue; - - for (x = 0; x < 8; x++) { - if (p->sample_rate < - (samplerates[x] + samplerates[x + 1]) / 2) - break; - } - if (x == 8) - return EINVAL; - - p->sample_rate = samplerates[x]; + x = neo_rate2index(p->sample_rate); nm_loadcoeff(sc, mode, x); x <<= 4; x &= NM_RATE_MASK; - if (p->precision == 16) - x |= NM_RATE_BITS_16; - if (p->channels == 2) - x |= NM_RATE_STEREO; + x |= NM_RATE_BITS_16; + x |= NM_RATE_STEREO; base = (mode == AUMODE_PLAY)? NM_PLAYBACK_REG_OFFSET : NM_RECORD_REG_OFFSET; nm_wr_1(sc, base + NM_RATE_REG_OFFSET, x); - - fil = mode == AUMODE_PLAY ? pfil : rfil; - i = auconv_set_converter(neo_formats, NEO_NFORMATS, - mode, p, FALSE, fil); - if (i < 0) - return EINVAL; } return 0; @@ -839,7 +767,8 @@ neo_round_blocksize(void *addr, int blk, const audio_params_t *param) { - return NM_BUFFSIZE / 2; + /* The number of blocks must be 3 or greater. */ + return NM_BUFFSIZE / 4; } static int @@ -891,6 +820,10 @@ neo_trigger_input(void *addr, void *star sc->rblksize = blksize; sc->rwmark = blksize; + /* + * XXX Doesn't it need to subtract ssz from BUFFER_END like + * trigger_output()? + */ nm_wr_4(sc, NM_RBUFFER_START, sc->rbuf); nm_wr_4(sc, NM_RBUFFER_END, sc->rbuf + sc->rbufsize); nm_wr_4(sc, NM_RBUFFER_CURRP, sc->rbuf); @@ -1011,26 +944,6 @@ neo_round_buffersize(void *addr, int dir return NM_BUFFSIZE; } -static paddr_t -neo_mappage(void *addr, void *mem, off_t off, int prot) -{ - struct neo_softc *sc; - vaddr_t v; - bus_addr_t pciaddr; - - sc = addr; - v = (vaddr_t)mem; - if (v == sc->pbuf_vaddr) - pciaddr = sc->pbuf_pciaddr; - else if (v == sc->rbuf_vaddr) - pciaddr = sc->rbuf_pciaddr; - else - return -1; - - return bus_space_mmap(sc->bufiot, pciaddr, off, prot, - BUS_SPACE_MAP_LINEAR); -} - static int neo_get_props(void *addr) {