Added IEC958 support for Cirrus Logic..

This commit is contained in:
Jaroslav Kysela 1998-10-31 19:51:05 +00:00
parent ec275f84ed
commit 6c20f0e73f
3 changed files with 113 additions and 10 deletions

View file

@ -57,6 +57,19 @@ playback return L_PLAYBACK;
record return L_RECORD;
output return L_OUTPUT;
input return L_INPUT;
iec958ocs return L_IEC958OCS;
3d return L_3D;
reset return L_RESET;
user return L_USER;
valid return L_VALID;
data return L_DATA;
protected return L_PROTECTED;
pre2 return L_PRE2;
fslock return L_FSLOCK;
type return L_TYPE;
gstatus return L_GSTATUS;
enable return L_ENABLE;
disable return L_DISABLE;
/* boolean */

View file

@ -60,6 +60,8 @@ static void select_rawmidi_input_switch( char *name );
static void set_switch_boolean( int val );
static void set_switch_integer( int val );
static void set_switch_iec958ocs_begin( void );
static void set_switch_iec958ocs( int idx, unsigned short val, unsigned short mask );
/* local variables */
@ -98,6 +100,8 @@ static void *Xswitch = NULL;
/* other keywords */
%token L_SOUNDCARD L_MIXER L_CHANNEL L_STEREO L_MONO L_SWITCH L_RAWDATA
%token L_CONTROL L_PCM L_RAWMIDI L_PLAYBACK L_RECORD L_OUTPUT L_INPUT
%token L_IEC958OCS L_3D L_RESET L_USER L_VALID L_DATA L_PROTECTED L_PRE2
%token L_FSLOCK L_TYPE L_GSTATUS L_ENABLE L_DISABLE
%type <b_value> boolean
%type <i_value> integer
@ -208,9 +212,28 @@ switches : switch
switch : L_TRUE { set_switch_boolean( 1 ); }
| L_FALSE { set_switch_boolean( 0 ); }
| L_INTEGER { set_switch_integer( $1 ); }
| L_IEC958OCS '(' { set_switch_iec958ocs_begin(); } iec958ocs ')'
| error { yyerror( "unknown keyword in switch() data parameter" ); }
;
iec958ocs : iec958ocs1
| iec958ocs iec958ocs1
;
iec958ocs1 : L_ENABLE { set_switch_iec958ocs( 0, 1, 0 ); }
| L_DISABLE { set_switch_iec958ocs( 0, 0, 0 ); }
| L_3D { set_switch_iec958ocs( 4, 0x2000, ~0x2000 ); }
| L_RESET { set_switch_iec958ocs( 4, 0x0040, ~0x0040 ); }
| L_USER { set_switch_iec958ocs( 4, 0x0020, ~0x0020 ); }
| L_VALID { set_switch_iec958ocs( 4, 0x0010, ~0x0010 ); }
| L_DATA { set_switch_iec958ocs( 5, 0x0002, ~0x0002 ); }
| L_PRE2 { set_switch_iec958ocs( 5, 0x0008, ~0x0018 ); }
| L_FSLOCK { set_switch_iec958ocs( 5, 0x0020, ~0x0020 ); }
| L_TYPE '(' integer ')' { set_switch_iec958ocs( 5, ($3 & 0x7f) << 6, ~(0x7f<<6) ); }
| L_GSTATUS { set_switch_iec958ocs( 5, 0x2000, ~0x2000 ); }
| error { yyerror( "unknown keyword in iec958ocs1() arguments" ); }
;
boolean : L_TRUE { $$ = 1; }
| L_FALSE { $$ = 0; }
| error { yyerror( "unknown boolean value" ); }
@ -434,3 +457,31 @@ static void set_switch_integer( int val )
if ( memcmp( &sw -> value, &xx, sizeof(xx) ) ) *Xswitchchange = 1;
memcpy( &sw -> value, &xx, sizeof(xx) );
}
static void set_switch_iec958ocs_begin( void )
{
/* ok.. this is a little bit wrong, but at these times are all switches same */
snd_ctl_switch_t *sw = (snd_ctl_switch_t *)Xswitch;
if ( Xswitchtype != SWITCH_MIXER || sw -> type != SND_MIXER_SW_TYPE_BOOLEAN ||
!strcmp( sw -> name, SND_MIXER_SW_IEC958OUT ) )
yyerror( "Switch '%s' cannot store IEC958 information for Cirrus Logic chips...", sw -> name );
if ( sw -> value.data32[1] != (('C'<<8)|'S') )
yyerror( "Switch '%s' doesn't have Cirrus Logic signature!!!", sw -> name );
sw -> value.enable = 0;
sw -> value.data16[4] = 0x0000;
sw -> value.data16[5] = 0x0000;
}
static void set_switch_iec958ocs( int idx, unsigned short val, unsigned short mask )
{
/* ok.. this is a little bit wrong, but at these times are all switches same */
snd_ctl_switch_t *sw = (snd_ctl_switch_t *)Xswitch;
if ( idx == 0 ) {
sw -> value.enable = val ? 1 : 0;
return;
}
sw -> value.data16[ idx ] &= ~mask;
sw -> value.data16[ idx ] |= val;
}

View file

@ -528,7 +528,8 @@ static void soundcard_setup_write_switch( FILE *out, int interface, const unsign
};
char *s, v[16];
struct data *pdata = (struct data *)data;
int idx;
int idx, first, switchok = 0;
const char *space = " ";
v[0] = '\0';
switch ( type ) {
@ -540,10 +541,47 @@ static void soundcard_setup_write_switch( FILE *out, int interface, const unsign
default:
s = "unknown";
}
fprintf( out, " ; Type is '%s'.\n", s );
fprintf( out, "%s; Type is '%s'.\n", space, s );
if ( low != 0 || high != 0 )
fprintf( out, " ; Accepted switch range is from %ui to %ui.\n", low, high );
fprintf( out, " switch( \"%s\", %s", name, v );
fprintf( out, "%s; Accepted switch range is from %ui to %ui.\n", space, low, high );
if ( interface == SND_INTERFACE_CONTROL && type == SND_CTL_SW_TYPE_WORD &&
!strcmp( name, SND_CTL_SW_JOYSTICK_ADDRESS ) ) {
for ( idx = 1, first = 1; idx < 16; idx++ ) {
if ( pdata -> data16[idx] ) {
if ( first ) {
fprintf( out, "%s; Available addresses - 0x%x", space, pdata -> data16[idx] );
first = 0;
} else {
fprintf( out, ", 0x%x", pdata -> data16[idx] );
}
}
}
if ( !first ) fprintf( out, "\n" );
}
fprintf( out, "%sswitch( \"%s\", ", space, name );
if ( interface == SND_INTERFACE_MIXER && type == SND_MIXER_SW_TYPE_BOOLEAN &&
!strcmp( name, SND_MIXER_SW_IEC958OUT ) ) {
if ( pdata -> data16[0] == (('C'<<8)|'S') ) { /* Cirrus Crystal */
switchok = 0;
fprintf( out, "iec958ocs( %s", pdata -> enable ? "enable" : "disable" );
if ( pdata -> data16[4] & 0x2000 ) fprintf( out, " 3d" );
if ( pdata -> data16[4] & 0x0040 ) fprintf( out, " reset" );
if ( pdata -> data16[4] & 0x0020 ) fprintf( out, " user" );
if ( pdata -> data16[4] & 0x0010 ) fprintf( out, " valid" );
if ( pdata -> data16[5] & 0x0002 ) fprintf( out, " data" );
if ( !(pdata -> data16[5] & 0x0004) ) fprintf( out, " protected" );
switch ( pdata -> data16[5] & 0x0018 ) {
case 0x0008: fprintf( out, " pre2" ); break;
default: break;
}
if ( pdata -> data16[5] & 0x0020 ) fprintf( out, " fslock" );
fprintf( out, " type( 0x%x )", (pdata -> data16[5] >> 6) & 0x7f );
if ( pdata -> data16[5] & 0x2000 ) fprintf( out, " gstatus" );
fprintf( out, ")" );
}
}
if ( !switchok ) {
fprintf( out, v );
if ( type < 0 || type > SND_CTL_SW_TYPE_DWORD ) {
/* TODO: some well known types should be verbose */
fprintf( out, " rawdata( " );
@ -552,6 +590,7 @@ static void soundcard_setup_write_switch( FILE *out, int interface, const unsign
}
fprintf( out, "%02x@ )\n", pdata -> data8[31] );
}
}
fprintf( out, " )\n" );
}