]> git.alsa-project.org Git - alsa-utils.git/commitdiff
Added IEC958 support for Cirrus Logic..
authorJaroslav Kysela <perex@perex.cz>
Sat, 31 Oct 1998 19:51:05 +0000 (19:51 +0000)
committerJaroslav Kysela <perex@perex.cz>
Sat, 31 Oct 1998 19:51:05 +0000 (19:51 +0000)
alsactl/alsactl_lexer.l
alsactl/alsactl_parser.y
alsactl/setup.c

index 3283b3e104759b1f436694c45e2f4e98acd53d35..a4728527e58709dfd311bd05d9e130b759e8fa58 100644 (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 */
 
index 79a41a32f69979fba445a1f0aac5c4716688c694..63395bc8838dc5d0c6b92f6c86c5d0de6063b165 100644 (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;
+}
index abebdb46d1412f6f46f9b0c04d9284e40c58013a..df0e6e3060db203778d014e2d54a32d20e7a5727 100644 (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,17 +541,55 @@ 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 );
-  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" );
 }