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 */
/* 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
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" ); }
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;
+}
};
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 ) {
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 );
- if ( type < 0 || type > SND_CTL_SW_TYPE_DWORD ) {
- /* TODO: some well known types should be verbose */
- fprintf( out, " rawdata( " );
- for ( idx = 0; idx < 31; idx++ ) {
- fprintf( out, "@%02x:", pdata -> data8[idx] );
- }
- fprintf( out, "%02x@ )\n", pdata -> data8[31] );
+ 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( " );
+ for ( idx = 0; idx < 31; idx++ ) {
+ fprintf( out, "@%02x:", pdata -> data8[idx] );
+ }
+ fprintf( out, "%02x@ )\n", pdata -> data8[31] );
+ }
}
fprintf( out, " )\n" );
}