Date: Tue, 9 Feb 1999 21:28:58 +0100 (MET) From: Luigi Rizzo <luigi@labinfo.iet.unipi.it> To: serg@bcs.zp.ua (Sergey Shkonda) Cc: luigi@iet.unipi.it, multimedia@FreeBSD.ORG Subject: Re: CS423[567] speed selection Message-ID: <199902092028.VAA16204@labinfo.iet.unipi.it> In-Reply-To: <199902082108.XAA03185@bcs3.bcs.zp.ua> from "Sergey Shkonda" at Feb 8, 99 11:07:59 pm
next in thread | previous 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)
thanks -- forgive me if i will not have the time to integrate this in
3.1 but the time is too short.
I was wondering, would it be difficult for you to add support for the
global volume control and the extended input mixer ? They are
accessible through the extended registers arent they ?
thanks
luigi
>
> --- 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?199902092028.VAA16204>
