Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 8 Feb 1999 23:08:18 +0200 (EET)
From:      Sergey Shkonda <serg@bcs.zp.ua>
To:        luigi@iet.unipi.it
Cc:        multimedia@FreeBSD.ORG
Subject:   CS423[567] speed selection
Message-ID:  <199902082108.XAA03185@bcs3.bcs.zp.ua>

next in thread | raw e-mail | index | archive | help
 I've implemented alternate speed selecttion for CS4236.
This patch allow sample rates in range 5.512 - 50.4 kHz
and different record/play rates can be used.

I've tested it with CS4235 (FreeBSD 2.2.8-R)


--- o/mss.h	Wed Jun 10 20:37:01 1998
+++ mss.h	Mon Feb  8 21:33:07 1999
@@ -99,6 +99,17 @@
 #define	I9_CEN		0x02	/* capture enable */
 
 /*
+ * register I23 -- extended register access
+ */
+#define	I23_XRAE	0x08	/* eXtended Registers Access Enable */
+#define	I23_XA_AMASK	0xf4
+#define	I23_REG(r)	( (((r)<<4)&0xf0) | (((r)<16)?0:0x04))
+
+/*
+ * Extended register X11
+ */
+#define	X11_IFSE	0x20	/* Independed FS Enable */
+/*
  * values used in bd_flags
  */
 #define	BD_F_MCE_BIT	0x0001


--- o/ad1848.c	Mon Feb  8 18:38:59 1999
+++ ad1848.c	Mon Feb  8 22:02:59 1999
@@ -78,6 +78,8 @@
 static void ad_write(snddev_info *d, int reg, u_char data);
 static void ad_write_cnt(snddev_info *d, int reg, u_short data);
 static int ad_read(snddev_info *d, int reg);
+static int ax_read(snddev_info *d, int reg);
+static void ax_write(snddev_info *d, int reg, u_char data);
 
 /*
  * device descriptors for the boards supported by this module.
@@ -724,6 +726,37 @@
     ad_write(d, reg, cnt >> 8 ); /* upper base must be last */
 }
 
+static int
+ax_read(snddev_info *d, int reg)
+{
+    u_long   flags;
+    int             x;
+
+    flags = spltty();
+    AD_WAIT_INIT(d, 201);
+    x = inb(io_Index_Addr(d)) & ~IA_AMASK ;
+    outb(io_Index_Addr(d), (u_char) (23 & IA_AMASK) | x ) ;
+    outb(io_Indexed_Data(d), (u_char) I23_XRAE | I23_REG(reg) ) ;
+    x = inb(io_Indexed_Data(d));
+    splx(flags);
+    return x;
+}
+
+static void
+ax_write(snddev_info *d, int reg, u_char data)
+{
+    u_long   flags;
+
+    int x ;
+    flags = spltty();
+    AD_WAIT_INIT(d, 1002);
+    x = inb(io_Index_Addr(d)) & ~IA_AMASK ;
+    outb(io_Index_Addr(d), (u_char) (23 & IA_AMASK) | x ) ;
+    outb(io_Indexed_Data(d), (u_char) I23_XRAE | I23_REG(reg) ) ;
+    outb(io_Indexed_Data(d), data);
+    splx(flags);
+}
+
 static void
 wait_for_calibration(snddev_info *d)
 {
@@ -976,6 +1009,27 @@
     }
 }
 
+static int
+cs4236_rate(int rate, int f)
+{
+    static int speeds [] = {
+	50400, 48000, 32000, 27420,
+	16000,  9600,  8000,  6620
+    };
+    int i;
+    int	newrate;
+    for (i = 0; i < 8; i++)
+	    if (rate == speeds[i])
+		    return (f ? speeds[i] : i);
+    i = 1058400 / rate; /* 16.9344 MHz / (16*rate) */
+    if (i < 21) /* too fast */
+	    i = 21;
+    if (i > 192) /* too slow */
+	    i = 192;
+    newrate = 1058400 / i;
+    return (f ? newrate : i);
+}
+
 /*
  * mss_speed processes the value in play_speed finding the
  * matching one. As a side effect, it returns the value to
@@ -1013,7 +1067,13 @@
 	if (speeds[i] >0 && abs(arg-speeds[i]) < abs(arg-speeds[sel]) )
 	    sel = i ;
 
-    d->play_speed = d->rec_speed = speeds[sel] ;
+    if ( d->bd_id == MD_CS4236 || d->bd_id == MD_CS4237 )
+    {
+	d->play_speed = cs4236_rate(d->play_speed, 1);
+	d->rec_speed  = cs4236_rate(d->rec_speed, 1);
+    }
+    else
+	d->play_speed = d->rec_speed = speeds[sel] ;
     return sel ;
 }
 
@@ -1338,8 +1398,12 @@
 	/*
 	 * set mode2 bit for dual dma op. This bit is not implemented
 	 * on the OPTi931
+	 * (set mode3 for CS4236/CS4237)
 	 */
-	ad_write(d, 12, ad_read(d, 12) | 0x40 /* mode 2 on the CS42xx */ );
+	if ( d->bd_id == MD_CS4236 || d->bd_id == MD_CS4237 )
+	    ad_write(d, 12, ad_read(d, 12) | 0x60 /* mode 3 on the CS4236 */ );
+	else
+	    ad_write(d, 12, ad_read(d, 12) | 0x40 /* mode 2 on the CS42xx */ );
 
     /*
      * XXX this should really go into mss-speed...
@@ -1354,6 +1418,18 @@
 	 */
     }
 
+    /*
+     * XXX set sample rate for 4236/4237
+     */
+    if ( d->bd_id == MD_CS4236 || d->bd_id == MD_CS4237 )
+    {
+	    /* Enable IFSE in X11 */
+	    ax_write (d, 11, ax_read (d, 11) | X11_IFSE);
+	    /* ADC rate */
+	    ax_write (d, 12, (u_char) cs4236_rate (d->rec_speed, 0));
+	    /* DAC rate */
+	    ax_write (d, 13, (u_char) cs4236_rate (d->play_speed, 0));
+    }
     ad_write(d, 8, r) ;
     if ( FULL_DUPLEX(d) ) {
 #if 0

--
Sergey Shkonda           <serg@bcs.zp.ua>


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-multimedia" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199902082108.XAA03185>