Catch up vs_set_params() to recent MI audio (after in-kernel mixer).
Before that, MD part had to support all encodings I'd like to support, but currently it's no longer necessary. The hardware is 4bit/1ch/15.6kHz ADPCM but it behaves as 16bit/1ch/16.0kHz PCM. For audio.c < 1.362, the device attach succeeded and playback is still working. For audio.c >= 1.363, the device attach fails again. It does not work yet but I commit it for milestone.
This commit is contained in:
parent
53779488e1
commit
5c899c2dfd
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: vs.c,v 1.38 2017/06/25 06:26:40 isaki Exp $ */
|
/* $NetBSD: vs.c,v 1.39 2017/07/09 12:49:26 isaki Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001 Tetsuya Isaki. All rights reserved.
|
* Copyright (c) 2001 Tetsuya Isaki. All rights reserved.
|
||||||
@ -30,7 +30,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: vs.c,v 1.38 2017/06/25 06:26:40 isaki Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: vs.c,v 1.39 2017/07/09 12:49:26 isaki Exp $");
|
||||||
|
|
||||||
#include "audio.h"
|
#include "audio.h"
|
||||||
#include "vs.h"
|
#include "vs.h"
|
||||||
@ -160,19 +160,6 @@ struct {
|
|||||||
|
|
||||||
#define NUM_RATE (sizeof(vs_l2r)/sizeof(vs_l2r[0]))
|
#define NUM_RATE (sizeof(vs_l2r)/sizeof(vs_l2r[0]))
|
||||||
|
|
||||||
struct {
|
|
||||||
const char *name;
|
|
||||||
int encoding;
|
|
||||||
int precision;
|
|
||||||
} vs_encodings[] = {
|
|
||||||
{AudioEadpcm, AUDIO_ENCODING_ADPCM, 4},
|
|
||||||
{AudioEslinear, AUDIO_ENCODING_SLINEAR, 8},
|
|
||||||
{AudioEulinear, AUDIO_ENCODING_ULINEAR, 8},
|
|
||||||
{AudioEmulaw, AUDIO_ENCODING_ULAW, 8},
|
|
||||||
{AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 16},
|
|
||||||
{AudioEslinear_le, AUDIO_ENCODING_SLINEAR_LE, 16},
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vs_match(device_t parent, cfdata_t cf, void *aux)
|
vs_match(device_t parent, cfdata_t cf, void *aux)
|
||||||
{
|
{
|
||||||
@ -338,17 +325,15 @@ vs_query_encoding(void *hdl, struct audio_encoding *fp)
|
|||||||
{
|
{
|
||||||
|
|
||||||
DPRINTF(1, ("vs_query_encoding\n"));
|
DPRINTF(1, ("vs_query_encoding\n"));
|
||||||
if (fp->index >= sizeof(vs_encodings) / sizeof(vs_encodings[0]))
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
strcpy(fp->name, vs_encodings[fp->index].name);
|
if (fp->index == 0) {
|
||||||
fp->encoding = vs_encodings[fp->index].encoding;
|
strcpy(fp->name, AudioEslinear_be);
|
||||||
fp->precision = vs_encodings[fp->index].precision;
|
fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
|
||||||
if (fp->encoding == AUDIO_ENCODING_ADPCM)
|
fp->precision = 16;
|
||||||
fp->flags = 0;
|
fp->flags = 0;
|
||||||
else
|
return 0;
|
||||||
fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
|
}
|
||||||
return 0;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -385,95 +370,48 @@ vs_set_params(void *hdl, int setmode, int usemode,
|
|||||||
stream_filter_list_t *pfil, stream_filter_list_t *rfil)
|
stream_filter_list_t *pfil, stream_filter_list_t *rfil)
|
||||||
{
|
{
|
||||||
struct vs_softc *sc;
|
struct vs_softc *sc;
|
||||||
struct audio_params *p;
|
|
||||||
int mode;
|
|
||||||
int rate;
|
int rate;
|
||||||
audio_params_t hw;
|
|
||||||
int matched;
|
|
||||||
|
|
||||||
DPRINTF(1, ("vs_set_params: setmode=%d, usemode=%d\n",
|
|
||||||
setmode, usemode));
|
|
||||||
|
|
||||||
sc = hdl;
|
sc = hdl;
|
||||||
/* set first record info, then play info */
|
|
||||||
for (mode = AUMODE_RECORD; mode != -1;
|
|
||||||
mode = (mode == AUMODE_RECORD) ? AUMODE_PLAY : -1) {
|
|
||||||
if ((setmode & mode) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
p = (mode == AUMODE_PLAY) ? play : rec;
|
DPRINTF(1, ("vs_set_params: mode=%d enc=%d rate=%d prec=%d ch=%d: ",
|
||||||
|
setmode, play->encoding, play->sample_rate,
|
||||||
|
play->precision, play->channels));
|
||||||
|
|
||||||
if (p->channels != 1)
|
if (play->channels != 1) {
|
||||||
return EINVAL;
|
DPRINTF(1, ("channels not matched\n"));
|
||||||
|
return EINVAL;
|
||||||
rate = p->sample_rate;
|
|
||||||
hw = *p;
|
|
||||||
hw.encoding = AUDIO_ENCODING_ADPCM;
|
|
||||||
hw.precision = hw.validbits = 4;
|
|
||||||
DPRINTF(1, ("vs_set_params: encoding=%d, precision=%d\n",
|
|
||||||
p->encoding, p->precision));
|
|
||||||
matched = 0;
|
|
||||||
switch (p->precision) {
|
|
||||||
case 4:
|
|
||||||
if (p->encoding == AUDIO_ENCODING_ADPCM)
|
|
||||||
matched = 1;
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
switch (p->encoding) {
|
|
||||||
case AUDIO_ENCODING_ULAW:
|
|
||||||
matched = 1;
|
|
||||||
hw.encoding = AUDIO_ENCODING_ULINEAR_LE;
|
|
||||||
hw.precision = hw.validbits = 8;
|
|
||||||
pfil->prepend(pfil, mulaw_to_linear8, &hw);
|
|
||||||
hw.encoding = AUDIO_ENCODING_ADPCM;
|
|
||||||
hw.precision = hw.validbits = 4;
|
|
||||||
pfil->prepend(pfil, msm6258_linear8_to_adpcm, &hw);
|
|
||||||
rfil->append(rfil, msm6258_adpcm_to_linear8, &hw);
|
|
||||||
hw.encoding = AUDIO_ENCODING_ULINEAR_LE;
|
|
||||||
hw.precision = hw.validbits = 8;
|
|
||||||
rfil->append(rfil, linear8_to_mulaw, &hw);
|
|
||||||
break;
|
|
||||||
case AUDIO_ENCODING_SLINEAR:
|
|
||||||
case AUDIO_ENCODING_SLINEAR_LE:
|
|
||||||
case AUDIO_ENCODING_SLINEAR_BE:
|
|
||||||
case AUDIO_ENCODING_ULINEAR:
|
|
||||||
case AUDIO_ENCODING_ULINEAR_LE:
|
|
||||||
case AUDIO_ENCODING_ULINEAR_BE:
|
|
||||||
matched = 1;
|
|
||||||
pfil->append(pfil, msm6258_linear8_to_adpcm, &hw);
|
|
||||||
rfil->append(rfil, msm6258_adpcm_to_linear8, &hw);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 16:
|
|
||||||
switch (p->encoding) {
|
|
||||||
case AUDIO_ENCODING_SLINEAR_LE:
|
|
||||||
case AUDIO_ENCODING_SLINEAR_BE:
|
|
||||||
matched = 1;
|
|
||||||
pfil->append(pfil, msm6258_slinear16_to_adpcm, &hw);
|
|
||||||
rfil->append(rfil, msm6258_adpcm_to_slinear16, &hw);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (matched == 0) {
|
|
||||||
DPRINTF(1, ("vs_set_params: mode=%d, encoding=%d\n",
|
|
||||||
mode, p->encoding));
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINTF(1, ("vs_set_params: rate=%d -> ", rate));
|
|
||||||
rate = vs_round_sr(rate);
|
|
||||||
DPRINTF(1, ("%d\n", rate));
|
|
||||||
if (rate < 0)
|
|
||||||
return EINVAL;
|
|
||||||
if (mode == AUMODE_PLAY) {
|
|
||||||
sc->sc_current.prate = rate;
|
|
||||||
} else {
|
|
||||||
sc->sc_current.rrate = rate;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rate = vs_round_sr(play->sample_rate);
|
||||||
|
if (rate < 0) {
|
||||||
|
DPRINTF(1, ("rate not matched\n"));
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (play->encoding != AUDIO_ENCODING_SLINEAR_BE) {
|
||||||
|
DPRINTF(1, ("encoding not matched\n"));
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
if (play->precision != 16) {
|
||||||
|
DPRINTF(1, ("precision not matched\n"));
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
play->encoding = AUDIO_ENCODING_ADPCM;
|
||||||
|
play->validbits = 4;
|
||||||
|
play->precision = 4;
|
||||||
|
|
||||||
|
pfil->prepend(pfil, msm6258_slinear16_to_adpcm, play);
|
||||||
|
rfil->prepend(rfil, msm6258_adpcm_to_slinear16, play);
|
||||||
|
|
||||||
|
sc->sc_current.prate = rate;
|
||||||
|
sc->sc_current.rrate = rate;
|
||||||
|
|
||||||
|
/* copy to rec because it's !AUDIO_PROP_INDEPENDENT */
|
||||||
|
*rec = *play;
|
||||||
|
|
||||||
|
DPRINTF(1, ("accepted\n"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user