Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev Add mode 3 support for newer CS423X chips. Modify p...



details:   https://anonhg.NetBSD.org/src/rev/df6ecf6d75e9
branches:  trunk
changeset: 476104:df6ecf6d75e9
user:      rh <rh%NetBSD.org@localhost>
date:      Mon Sep 06 17:07:04 1999 +0000

description:
Add mode 3 support for newer CS423X chips.  Modify probe to correctly
distinguish between CS4236, CS4236B, and CS4237B.

diffstat:

 sys/dev/ic/ad1848.c      |  48 ++++++++++++++++++++++++-----
 sys/dev/ic/ad1848reg.h   |   3 +-
 sys/dev/ic/ad1848var.h   |   4 +-
 sys/dev/ic/cs4237reg.h   |  77 ++++++++++++++++++++++++++++++++++++++++++++++++
 sys/dev/isa/ad1848_isa.c |  51 +++++++++++++++++++++++++++++--
 5 files changed, 168 insertions(+), 15 deletions(-)

diffs (truncated from 326 to 300 lines):

diff -r 52e039cf7d57 -r df6ecf6d75e9 sys/dev/ic/ad1848.c
--- a/sys/dev/ic/ad1848.c       Mon Sep 06 10:10:05 1999 +0000
+++ b/sys/dev/ic/ad1848.c       Mon Sep 06 17:07:04 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ad1848.c,v 1.5 1999/02/18 17:27:39 mycroft Exp $       */
+/*     $NetBSD: ad1848.c,v 1.6 1999/09/06 17:07:04 rh Exp $    */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -119,6 +119,7 @@
 
 #include <dev/ic/ad1848reg.h>
 #include <dev/ic/cs4231reg.h>
+#include <dev/ic/cs4237reg.h>
 #include <dev/ic/ad1848var.h>
 #if 0
 #include <dev/isa/cs4231var.h>
@@ -240,6 +241,35 @@
        /* printf("(%02x->%02x) ", reg|sc->MCE_bit, data); */
 }
 
+/*
+ * extended registers (mode 3) require an additional level of
+ * indirection through CS_XREG (I23).
+ */
+
+__inline int
+ad_xread(sc, reg)
+       struct ad1848_softc *sc;
+       int reg;
+{
+       int x;
+
+       ADWRITE(sc, AD1848_IADDR, CS_XREG | sc->MCE_bit);
+       ADWRITE(sc, AD1848_IDATA, (reg | ALT_F3_XRAE) & 0xff);
+       x = ADREAD(sc, AD1848_IDATA);
+
+       return x;
+}
+
+__inline void
+ad_xwrite(sc, reg, val)
+       struct ad1848_softc *sc;
+       int reg, val;
+{
+       ADWRITE(sc, AD1848_IADDR, CS_XREG | sc->MCE_bit);
+       ADWRITE(sc, AD1848_IDATA, (reg | ALT_F3_XRAE) & 0xff);
+       ADWRITE(sc, AD1848_IDATA, val & 0xff);
+}
+
 static void
 ad_set_MCE(sc, state)
        struct ad1848_softc *sc;
@@ -328,7 +358,7 @@
                r = ad_read(sc, i);
                printf("%02x ", r);
        }
-       if (sc->mode == 2) {
+       if (sc->mode >= 2) {
                for (i = 16; i < 32; i++) {
                        r = ad_read(sc, i);
                        printf("%02x ", r);
@@ -361,7 +391,7 @@
                        timeout--;
        }
        /* ...and additional CS4231 stuff too */
-       if (sc->mode == 2) {
+       if (sc->mode >= 2) {
                ad_write(sc, SP_INTERFACE_CONFIG, 0); /* disable SINGLE_DMA */
                for (i = 0x10; i < 0x20; i++)
                        if (ad1848_init_values[i] != 0) {
@@ -383,7 +413,7 @@
        ad1848_set_channel_gain(sc, AD1848_DAC_CHANNEL, &vol_mid);
        ad1848_set_channel_gain(sc, AD1848_MONITOR_CHANNEL, &vol_0);
        ad1848_set_channel_gain(sc, AD1848_AUX1_CHANNEL, &vol_mid);     /* CD volume */
-       if (sc->mode == 2) {
+       if (sc->mode >= 2) {
                ad1848_set_channel_gain(sc, AD1848_AUX2_CHANNEL, &vol_mid); /* CD volume */
                ad1848_set_channel_gain(sc, AD1848_LINE_CHANNEL, &vol_mid);
                ad1848_set_channel_gain(sc, AD1848_MONO_CHANNEL, &vol_0);
@@ -553,7 +583,7 @@
        struct ad1848_softc *sc = addr;
 
        DPRINTF(("ad1848_mute_monitor: %smuting\n", mute ? "" : "un"));
-       if (sc->mode == 2) {
+       if (sc->mode >= 2) {
                ad1848_mute_channel(sc, AD1848_DAC_CHANNEL,
                                    mute ? MUTE_ALL : 0);
                ad1848_mute_channel(sc, AD1848_MONO_CHANNEL,
@@ -957,7 +987,7 @@
                inp = LINE_INPUT;
        else if (port == DAC_IN_PORT)
                inp = MIXED_DAC_INPUT;
-       else if (sc->mode == 2 && port == AUX1_IN_PORT)
+       else if (sc->mode >= 2 && port == AUX1_IN_PORT)
                inp = AUX_INPUT;
        else
                return(EINVAL);
@@ -1065,10 +1095,10 @@
        ad_write(sc, SP_CLOCK_DATA_FORMAT, fs);
 
        /*
-        * If mode == 2 (CS4231), set I28 also.
+        * If mode >= 2 (CS4231), set I28 also.
         * It's the capture format register.
         */
-       if (sc->mode == 2) {
+       if (sc->mode >= 2) {
                /*
                 * Gravis Ultrasound MAX SDK sources says something about
                 * errata sheets, with the implication that these inb()s
@@ -1124,7 +1154,7 @@
        r &= ~(CAPTURE_ENABLE | PLAYBACK_ENABLE);
        ad_write(sc, SP_INTERFACE_CONFIG, r);
 
-       if (sc->mode == 2) {
+       if (sc->mode >= 2) {
                ADWRITE(sc, AD1848_IADDR, CS_IRQ_STATUS);
                ADWRITE(sc, AD1848_IDATA, 0);
        }
diff -r 52e039cf7d57 -r df6ecf6d75e9 sys/dev/ic/ad1848reg.h
--- a/sys/dev/ic/ad1848reg.h    Mon Sep 06 10:10:05 1999 +0000
+++ b/sys/dev/ic/ad1848reg.h    Mon Sep 06 17:07:04 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ad1848reg.h,v 1.7 1998/08/27 20:05:11 pk Exp $ */
+/*     $NetBSD: ad1848reg.h,v 1.8 1999/09/06 17:07:05 rh Exp $ */
 
 /*
  * Copyright (c) 1994 John Brezak
@@ -166,6 +166,7 @@
 /* Miscellaneous Control reg bits - register I12 */
 #define ID_MASK                        0x70
 #define MODE2                  0x40
+#define MODE3                  0x60
 
 /* Digital Mix Control reg bits - register I13 */
 #define DIGITAL_MIX1_ENABLE    0x01
diff -r 52e039cf7d57 -r df6ecf6d75e9 sys/dev/ic/ad1848var.h
--- a/sys/dev/ic/ad1848var.h    Mon Sep 06 10:10:05 1999 +0000
+++ b/sys/dev/ic/ad1848var.h    Mon Sep 06 17:07:04 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ad1848var.h,v 1.4 1999/02/18 17:27:39 mycroft Exp $    */
+/*     $NetBSD: ad1848var.h,v 1.5 1999/09/06 17:07:05 rh Exp $ */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -150,7 +150,9 @@
 } ad1848_devmap_t;
 
 int    ad_read __P((struct ad1848_softc *, int));
+int    ad_xread __P((struct ad1848_softc *, int));
 void   ad_write __P((struct ad1848_softc *, int, int));
+void   ad_xwrite __P((struct ad1848_softc *, int, int));
 
 void   ad1848_attach __P((struct ad1848_softc *));
 void   ad1848_reset __P((struct ad1848_softc *));
diff -r 52e039cf7d57 -r df6ecf6d75e9 sys/dev/ic/cs4237reg.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/ic/cs4237reg.h    Mon Sep 06 17:07:04 1999 +0000
@@ -0,0 +1,77 @@
+/*     $NetBSD: cs4237reg.h,v 1.1 1999/09/06 17:07:05 rh Exp $ */
+
+/*
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Rene Hexel (rh%netbsd.org@localhost).
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* CS4237/4236B mode3 extended register, added to AD1848 registers */
+#define CS_XREG                        23      /* mode 3 extended register access */
+
+/* ALT_FEATURE3 - register I23 */
+#define ALT_F3_XA4             0x04    /* Extended Register Address bit 4 */
+#define ALT_F3_XRAE            0x08    /* Extended Register Access Enable */
+#define ALT_F3_XA0             0x10    /* Extended Register Address bit 0 */
+#define ALT_F3_XA1             0x20    /* Extended Register Address bit 1 */
+#define ALT_F3_XA2             0x40    /* Extended Register Address bit 2 */
+#define ALT_F3_XA3             0x80    /* Extended Register Address bit 3 */
+
+/* extended register set, accessed indirectly through I23 */
+#define CS_X_LEFT_LINE_ALT_VOL 0x08    /* Left LINE Alternate Volume */
+#define CS_X_RIGHT_LINE_ALT_VOL        0x18    /* Right LINE Alternate Volume */
+#define CS_X_LEFT_MIC_VOL      0x28    /* Left Microphone Volume */
+#define CS_X_RIGHT_MIC_VOL     0x38    /* Right Microphone Volume */
+#define CS_X_SYNTHINPUT_CONTROL        0x48    /* Synthesis and Input Mixer Control */
+#define CS_X_RIGHTINPUT_CONTROL        0x58    /* Right Input Mixer Control */
+#define CS_X_LEFT_FM_SYNTH_VOL 0x68    /* Left FM Synthesis Volume */
+#define CS_X_RIGHT_FM_SYNTH_VOL        0x78    /* Right FM Synthesis Volume */
+#define CS_X_LEFT_DSP_SER_VOL  0x88    /* Left DSP Serial Port Volume */
+#define CS_X_RIGHT_DSP_SER_VOL 0x98    /* Right DSP Serial Port Volume */
+#define CS_X_RIGHT_LOOPBACK_VOL        0xa8    /* Right Loopback Monitor Volume */
+#define CS_X_DAC_MUTE_IFSE_EN  0xb8    /* DAC Mute and IFSE Enable */
+#define CS_X_INDEP_ADC_FREQ    0xc8    /* Independendt ADC Sample Freq */
+#define CS_X_INDEP_DAC_FREQ    0xd8    /* Independendt DAC Sample Freq */
+#define CS_X_LEFT_DIGITAL_VOL  0xe8    /* Left Master Digital Audio Volume */
+#define CS_X_RIGHT_DIGITAL_VOL 0xf8    /* Right Master Digital Audio Volume */
+#define CS_X_LEFT_WAVE_SER_VOL 0x0c    /* Left Wavetable Serial Port Volume */
+#define CS_X_RIGHT_WAVE_SER_VOL        0x1c    /* Right Wavetable Serial Port Volume */
+#define CS_X_CHIP_VERSION      0x9c    /* Chip Version and ID */
+
+/* CS_X_CHIP_VERSION - register X25 */
+#define X_CHIP_VERSIONF_CID    0x1f    /* Chip ID mask */
+#define X_CHIP_VERSIONF_REV    0xe0    /* Chip Revision mask */
+
+#define X_CHIP_CID_CS4236BB    0x00    /* CS4236B revision B */
+#define X_CHIP_CID_CS4236B     0x0b    /* CS4236B other revision */
+#define X_CHIP_CID_CS4237B     0x08    /* CS4237B */
diff -r 52e039cf7d57 -r df6ecf6d75e9 sys/dev/isa/ad1848_isa.c
--- a/sys/dev/isa/ad1848_isa.c  Mon Sep 06 10:10:05 1999 +0000
+++ b/sys/dev/isa/ad1848_isa.c  Mon Sep 06 17:07:04 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ad1848_isa.c,v 1.11 1999/03/22 14:54:01 mycroft Exp $  */
+/*     $NetBSD: ad1848_isa.c,v 1.12 1999/09/06 17:07:05 rh Exp $       */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -124,6 +124,7 @@
 
 #include <dev/ic/ad1848reg.h>
 #include <dev/ic/cs4231reg.h>
+#include <dev/ic/cs4237reg.h>
 #include <dev/isa/ad1848var.h>
 #include <dev/isa/cs4231var.h>
 
@@ -330,6 +331,8 @@
                                goto bad;
                        }
 
+                       sc->mode = 2;
+
                        /*
                         *  It's a CS4231, or another clone with 32 registers.
                         *  Let's find out which by checking I25.
@@ -349,11 +352,51 @@
                                        break;
                                case 0x03:
                                case 0x83:
-                                       sc->chip_name = "CS4236/CS4236B";
+                                       sc->chip_name = "CS4236";
+
+                                       /*
+                                        * Try to switch to mode3 (CS4236B or
+                                        * CS4237B) by setting CMS to 3.  A
+                                        * plain CS4236 will not react to
+                                        * LLBM settings.
+                                        */
+                                       ad_write(sc, SP_MISC_INFO, MODE3);
+
+                                       tmp1 = ad_read(sc, CS_LEFT_LINE_CONTROL);
+                                       ad_write(sc, CS_LEFT_LINE_CONTROL, 0xe0);
+                                       tmp2 = ad_read(sc, CS_LEFT_LINE_CONTROL);
+                                       if (tmp2 == 0xe0) {
+                                               /*
+                                                * it's a CS4237B or another
+                                                * clone supporting mode 3.
+                                                * Let's determine which by
+                                                * enabling extended registers
+                                                * and checking X25.
+                                                */
+                                               tmp2 = ad_xread(sc, CS_X_CHIP_VERSION);
+                                               switch (tmp2 & X_CHIP_VERSIONF_CID) {
+                                               case X_CHIP_CID_CS4236BB:
+                                                       sc->chip_name = "CS4236BrevB";
+                                                       break;
+                                               case X_CHIP_CID_CS4236B:
+                                                       sc->chip_name = "CS4236B";
+                                                       break;
+                                               case X_CHIP_CID_CS4237B:
+                                                       sc->chip_name = "CS4237B";
+                                                       break;



Home | Main Index | Thread Index | Old Index