summaryrefslogtreecommitdiff
path: root/sys/dev/pci/auich.c
diff options
context:
space:
mode:
authorJacob Meuser <jakemsr@cvs.openbsd.org>2008-10-25 22:30:44 +0000
committerJacob Meuser <jakemsr@cvs.openbsd.org>2008-10-25 22:30:44 +0000
commitfe8114f730e5473eba5ee55c81c541e29edbeea8 (patch)
tree545de71dde8d0a2e03bc8556eeaa4beb581824dd /sys/dev/pci/auich.c
parentd54880b2f6a9ada7238d4417b82adb8ce1f2ae77 (diff)
audio(9) says low level drivers are allowed to change the requested
values of the audio_params structure during AUDIO_SETINFO if the hardware cannot be set to exactly the requested mode. some drivers do this sometimes. others always return EINVAL if there isn't an exact match. be more consistent. only return EINVAL if an absurd parameter was requested, otherwise return a supported set of parameters, as close as possible to what was requested. with/ok ratchov@
Diffstat (limited to 'sys/dev/pci/auich.c')
-rw-r--r--sys/dev/pci/auich.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/sys/dev/pci/auich.c b/sys/dev/pci/auich.c
index 97147001f97..e2b7e1b739c 100644
--- a/sys/dev/pci/auich.c
+++ b/sys/dev/pci/auich.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auich.c,v 1.76 2008/10/23 21:50:01 jakemsr Exp $ */
+/* $OpenBSD: auich.c,v 1.77 2008/10/25 22:30:43 jakemsr Exp $ */
/*
* Copyright (c) 2000,2001 Michael Shalayeff
@@ -748,16 +748,21 @@ auich_set_params(v, setmode, usemode, play, rec)
if (setmode & AUMODE_PLAY) {
/* only 16-bit 48kHz slinear_le if s/pdif enabled */
- if (sc->sc_spdif &&
- ((play->sample_rate != 48000) || (play->precision != 16) ||
- (play->encoding != AUDIO_ENCODING_SLINEAR_LE)))
- return (EINVAL);
+ if (sc->sc_spdif) {
+ play->sample_rate = 48000;
+ play->precision = 16;
+ play->encoding = AUDIO_ENCODING_SLINEAR_LE;
+ }
}
if (setmode & AUMODE_PLAY) {
play->factor = 1;
play->sw_code = NULL;
+ if (play->precision > 16)
+ play->precision = 16;
switch(play->encoding) {
case AUDIO_ENCODING_ULAW:
+ if (play->channels > 2)
+ play->channels = 2;
switch (play->channels) {
case 1:
play->factor = 4;
@@ -774,6 +779,8 @@ auich_set_params(v, setmode, usemode, play, rec)
case AUDIO_ENCODING_SLINEAR_LE:
switch (play->precision) {
case 8:
+ if (play->channels > 2)
+ play->channels = 2;
switch (play->channels) {
case 1:
play->factor = 4;
@@ -788,6 +795,10 @@ auich_set_params(v, setmode, usemode, play, rec)
}
break;
case 16:
+ if (play->channels > 6)
+ play->channels = 6;
+ if (play->channels > 1)
+ play->channels &= ~1;
switch (play->channels) {
case 1:
play->factor = 2;
@@ -798,23 +809,23 @@ auich_set_params(v, setmode, usemode, play, rec)
case 4:
ext_id = codec->vtbl->get_caps(codec);
if (!(ext_id & AC97_EXT_AUDIO_SDAC))
- return (EINVAL);
+ play->channels = 2;
break;
case 6:
ext_id = codec->vtbl->get_caps(codec);
if ((ext_id & AC97_BITS_6CH) !=
AC97_BITS_6CH)
- return (EINVAL);
+ play->channels = 2;
break;
default:
return (EINVAL);
}
break;
- default:
- return (EINVAL);
}
break;
case AUDIO_ENCODING_ULINEAR_LE:
+ if (play->channels > 2)
+ play->channels = 2;
switch (play->precision) {
case 8:
switch (play->channels) {
@@ -848,6 +859,8 @@ auich_set_params(v, setmode, usemode, play, rec)
}
break;
case AUDIO_ENCODING_ALAW:
+ if (play->channels > 2)
+ play->channels = 2;
switch (play->channels) {
case 1:
play->factor = 4;
@@ -862,6 +875,8 @@ auich_set_params(v, setmode, usemode, play, rec)
}
break;
case AUDIO_ENCODING_SLINEAR_BE:
+ if (play->channels > 2)
+ play->channels = 2;
switch (play->precision) {
case 8:
switch (play->channels) {
@@ -895,6 +910,8 @@ auich_set_params(v, setmode, usemode, play, rec)
}
break;
case AUDIO_ENCODING_ULINEAR_BE:
+ if (play->channels > 2)
+ play->channels = 2;
switch (play->precision) {
case 8:
switch (play->channels) {
@@ -968,6 +985,10 @@ auich_set_params(v, setmode, usemode, play, rec)
if (setmode & AUMODE_RECORD) {
rec->factor = 1;
rec->sw_code = 0;
+ if (rec->channels > 2)
+ rec->channels = 2;
+ if (rec->precision > 16)
+ rec->precision = 16;
switch(rec->encoding) {
case AUDIO_ENCODING_ULAW:
switch (rec->channels) {