Update of /cvsroot/alsa/alsa-kernel/pci/ice1712
In directory sc8-pr-cvs1:/tmp/cvs-serv29463/pci/ice1712

Modified Files:
        Makefile ak4xxx.c ice1712.c ice1724.c revo.c 
Added Files:
        aureon.c aureon.h 
Log Message:
added the support of Terratec Aureon boards

--- NEW FILE: aureon.c ---
/*
 *   ALSA driver for ICEnsemble VT1724 (Envy24HT)
 *
 *   Lowlevel functions for Terratec Aureon cards
 *
 *      Copyright (c) 2003 Takashi Iwai <[EMAIL PROTECTED]>
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 *
 * NOTES:
 *
 * - we reuse the akm4xxx_t record for storing the wm8770 codec data.
 *   both wm and akm codecs are pretty similar, so we can integrate
 *   both controls in the future, once if wm codecs are reused in
 *   many boards.
 *
 * - writing over SPI is implemented but reading is not yet.
 *   the SPDIF-in channel status, etc. can be read from CS chip.
 *
 * - DAC digital volumes are not implemented in the mixer.
 *   if they show better response than DAC analog volumes, we can use them
 *   instead.
 *
 * - Aureon boards are equipped with AC97 codec, too.  it's used to do
 *   the analog mixing but not easily controllable (it's not connected
 *   directly from envy24ht chip).  so let's leave it as it is.
 *
 */      

#include <sound/driver.h>
#include <asm/io.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <sound/core.h>

#include "ice1712.h"
#include "envy24ht.h"
#include "aureon.h"

/* WM8770 registers */
#define WM_DAC_ATTEN            0x00    /* DAC1-8 analog attenuation */
#define WM_DAC_MASTER_ATTEN     0x08    /* DAC master analog attenuation */
#define WM_DAC_DIG_ATTEN        0x09    /* DAC1-8 digital attenuation */
#define WM_DAC_DIG_MATER_ATTEN  0x11    /* DAC master digital attenuation */
#define WM_PHASE_SWAP           0x12    /* DAC phase */
#define WM_DAC_CTRL1            0x13    /* DAC control bits */
#define WM_MUTE                 0x14    /* mute controls */
#define WM_DAC_CTRL2            0x15    /* de-emphasis and zefo-flag */
#define WM_INT_CTRL             0x16    /* interface control */
#define WM_MASTER               0x17    /* master clock and mode */
#define WM_POWERDOWN            0x18    /* power-down controls */
#define WM_ADC_GAIN             0x19    /* ADC gain L(19)/R(1a) */
#define WM_ADC_MUX              0x1b    /* input MUX */
#define WM_OUT_MUX1             0x1c    /* output MUX */
#define WM_OUT_MUX2             0x1e    /* output MUX */
#define WM_RESET                0x1f    /* software reset */


/*
 * write data in the SPI mode
 */
static void aureon_spi_write(ice1712_t *ice, unsigned int cs, unsigned int data, int 
bits)
{
        unsigned int tmp;
        int i;

        tmp = snd_ice1712_gpio_read(ice);

        snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RW|AUREON_WM_DATA|AUREON_WM_CLK|
                                         AUREON_WM_CS|AUREON_CS8415_CS));
        tmp |= AUREON_WM_RW;
        tmp &= ~cs;
        snd_ice1712_gpio_write(ice, tmp);
        udelay(1);

        for (i = bits - 1; i >= 0; i--) {
                tmp &= ~AUREON_WM_CLK;
                snd_ice1712_gpio_write(ice, tmp);
                udelay(1);
                if (data & (1 << i))
                        tmp |= AUREON_WM_DATA;
                else
                        tmp &= ~AUREON_WM_DATA;
                snd_ice1712_gpio_write(ice, tmp);
                udelay(1);
                tmp |= AUREON_WM_CLK;
                snd_ice1712_gpio_write(ice, tmp);
                udelay(1);
        }

        tmp &= ~AUREON_WM_CLK;
        tmp |= cs;
        snd_ice1712_gpio_write(ice, tmp);
        udelay(1);
        tmp |= AUREON_WM_CLK;
        snd_ice1712_gpio_write(ice, tmp);
        udelay(1);
}
     

/*
 * get the current register value of WM codec
 */
static unsigned short wm_get(ice1712_t *ice, int reg)
{
        reg <<= 1;
        return ((unsigned short)ice->akm[0].images[reg] << 8) |
                ice->akm[0].images[reg + 1];
}

/*
 * set the register value of WM codec and remember it
 */
static void wm_put(ice1712_t *ice, int reg, unsigned short val)
{
        aureon_spi_write(ice, AUREON_WM_CS, (reg << 9) | (val & 0x1ff), 16);
        reg <<= 1;
        ice->akm[0].images[reg] = val >> 8;
        ice->akm[0].images[reg + 1] = val;
}

/*
 * DAC volume attenuation mixer control
 */
static int wm_dac_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
{
        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
        uinfo->count = 1;
        uinfo->value.integer.min = 0;           /* mute */
        uinfo->value.integer.max = 101;         /* 0dB */
        return 0;
}

static int wm_dac_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
        ice1712_t *ice = snd_kcontrol_chip(kcontrol);
        int idx;
        unsigned short vol;

        down(&ice->gpio_mutex);
        if (kcontrol->private_value)
                idx = WM_DAC_MASTER_ATTEN;
        else
                idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + WM_DAC_ATTEN;
        vol = wm_get(ice, idx) & 0x7f;
        if (vol <= 0x1a)
                ucontrol->value.integer.value[0] = 0;
        else
                ucontrol->value.integer.value[0] = vol - 0x1a;
        up(&ice->gpio_mutex);
        return 0;
}

static int wm_dac_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
        ice1712_t *ice = snd_kcontrol_chip(kcontrol);
        int idx;
        unsigned short ovol, nvol;
        int change;

        snd_ice1712_save_gpio_status(ice);
        if (kcontrol->private_value)
                idx = WM_DAC_MASTER_ATTEN;
        else
                idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + WM_DAC_ATTEN;
        nvol = ucontrol->value.integer.value[0] + 0x1a;
        ovol = wm_get(ice, idx) & 0x7f;
        change = (ovol != nvol);
        if (change) {
                if (nvol <= 0x1a && ovol <= 0x1a)
                        change = 0;
                else
                        wm_put(ice, idx, nvol | 0x100);
        }
        snd_ice1712_restore_gpio_status(ice);
        return change;
}

/*
 * ADC gain mixer control
 */
static int wm_adc_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
{
        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
        uinfo->count = 1;
        uinfo->value.integer.min = 0;           /* -12dB */
        uinfo->value.integer.max = 0x1f;        /* 19dB */
        return 0;
}

static int wm_adc_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
        ice1712_t *ice = snd_kcontrol_chip(kcontrol);
        int idx;
        unsigned short vol;

        down(&ice->gpio_mutex);
        idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + WM_ADC_GAIN;
        vol = wm_get(ice, idx) & 0x1f;
        ucontrol->value.integer.value[0] = vol;
        up(&ice->gpio_mutex);
        return 0;
}

static int wm_adc_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
        ice1712_t *ice = snd_kcontrol_chip(kcontrol);
        int idx;
        unsigned short ovol, nvol;
        int change;

        snd_ice1712_save_gpio_status(ice);
        idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + WM_ADC_GAIN;
        nvol = ucontrol->value.integer.value[0];
        ovol = wm_get(ice, idx) & 0x1f;
        change = (ovol != nvol);
        if (change)
                wm_put(ice, idx, nvol);
        snd_ice1712_restore_gpio_status(ice);
        return change;
}

/*
 * ADC input mux mixer control
 */
static int wm_adc_mux_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
{
        static char *texts[] = {
                "CD Left",
                "CD Right",
                "Aux Left",
                "Aux Right",
                "Line Left",
                "Line Right",
                "Mic Left",
                "Mic Right",
        };
        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
        uinfo->count = 2;
        uinfo->value.enumerated.items = 8;
        if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
                uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
        strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
        return 0;
}

static int wm_adc_mux_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
{
        ice1712_t *ice = snd_kcontrol_chip(kcontrol);
        unsigned short val;

        down(&ice->gpio_mutex);
        val = wm_get(ice, WM_ADC_MUX);
        ucontrol->value.integer.value[0] = val & 7;
        ucontrol->value.integer.value[1] = (val >> 4) & 7;
        up(&ice->gpio_mutex);
        return 0;
}

static int wm_adc_mux_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
{
        ice1712_t *ice = snd_kcontrol_chip(kcontrol);
        unsigned short oval, nval;
        int change;

        snd_ice1712_save_gpio_status(ice);
        oval = wm_get(ice, WM_ADC_MUX);
        nval = oval & ~0x77;
        nval |= ucontrol->value.integer.value[0] & 7;
        nval |= (ucontrol->value.integer.value[1] & 7) << 4;
        change = (oval != nval);
        if (change)
                wm_put(ice, WM_ADC_MUX, nval);
        snd_ice1712_restore_gpio_status(ice);
        return 0;
}

/*
 * mixers
 */

static snd_kcontrol_new_t aureon51_dac_control __devinitdata = {
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
        .name = "DAC Volume",
        .count = 6,
        .info = wm_dac_vol_info,
        .get = wm_dac_vol_get,
        .put = wm_dac_vol_put,
};

static snd_kcontrol_new_t aureon71_dac_control __devinitdata = {
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
        .name = "DAC Volume",
        .count = 8,
        .info = wm_dac_vol_info,
        .get = wm_dac_vol_get,
        .put = wm_dac_vol_put,
};

static snd_kcontrol_new_t wm_controls[] __devinitdata = {
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "Master Playback Volume",
                .info = wm_dac_vol_info,
                .get = wm_dac_vol_get,
                .put = wm_dac_vol_put,
                .private_value = 1,
        },
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "ADC Volume",
                .count = 2,
                .info = wm_adc_vol_info,
                .get = wm_adc_vol_get,
                .put = wm_adc_vol_put,
        },
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "Capture Route",
                .info = wm_adc_mux_info,
                .get = wm_adc_mux_get,
                .put = wm_adc_mux_put,
        },
};


static int __devinit aureon_add_controls(ice1712_t *ice)
{
        unsigned int i;
        int err;

        if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY)
                err = snd_ctl_add(ice->card, snd_ctl_new1(&aureon51_dac_control, ice));
        else
                err = snd_ctl_add(ice->card, snd_ctl_new1(&aureon71_dac_control, ice));
        if (err < 0)
                return err;

        for (i = 0; i < ARRAY_SIZE(wm_controls); i++) {
                err = snd_ctl_add(ice->card, snd_ctl_new1(&wm_controls[i], ice));
                if (err < 0)
                        return err;
        }
        return 0;
}


/*
 * initialize the chip
 */
static int __devinit aureon_init(ice1712_t *ice)
{
        static unsigned short wm_inits[] = {
                0x16, 0x122,            /* I2S, normal polarity, 24bit */
                0x17, 0x022,            /* 256fs, slave mode */
                0x18, 0x000,            /* All power-up */
                0x00, 0,                /* DAC1 analog mute */
                0x01, 0,                /* DAC2 analog mute */
                0x02, 0,                /* DAC3 analog mute */
                0x03, 0,                /* DAC4 analog mute */
                0x04, 0,                /* DAC5 analog mute */
                0x05, 0,                /* DAC6 analog mute */
                0x06, 0,                /* DAC7 analog mute */
                0x07, 0,                /* DAC8 analog mute */
                0x08, 0x100,            /* master analog mute */
                0x09, 0xff,             /* DAC1 digital full */
                0x0a, 0xff,             /* DAC2 digital full */
                0x0b, 0xff,             /* DAC3 digital full */
                0x0c, 0xff,             /* DAC4 digital full */
                0x0d, 0xff,             /* DAC5 digital full */
                0x0e, 0xff,             /* DAC6 digital full */
                0x0f, 0xff,             /* DAC7 digital full */
                0x10, 0xff,             /* DAC8 digital full */
                0x11, 0x1ff,            /* master digital full */
                0x12, 0x000,            /* phase normal */
                0x13, 0x090,            /* unmute DAC L/R */
                0x14, 0x000,            /* all unmute */
                0x15, 0x000,            /* no deemphasis, no ZFLG */
                0x19, 0x000,            /* -12dB ADC/L */
                0x1a, 0x000,            /* -12dB ADC/R */
                0x1b, 0x000,            /* ADC Mux */
                0x1c, 0x009,            /* Out Mux1 */
                0x1d, 0x009,            /* Out Mux2 */
        };
        static unsigned short cs_inits[] = {
                0x0441, /* RUN */
                0x0100, /* no mute */
                0x0200, /* */
                0x0600, /* slave, 24bit */
        };
        unsigned int tmp;
        unsigned int i;

        if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY)
                ice->num_total_dacs = 6;
        else
                ice->num_total_dacs = 8;

        /* to remeber the register values */
        ice->akm = snd_kcalloc(sizeof(akm4xxx_t), GFP_KERNEL);
        if (! ice->akm)
                return -ENOMEM;
        ice->akm_codecs = 1;

        snd_ice1712_gpio_set_dir(ice, 0xbfffff); /* fix this for the time being */

        /* reset the wm codec as the SPI mode */
        snd_ice1712_save_gpio_status(ice);
        snd_ice1712_gpio_set_mask(ice, 
~(AUREON_WM_RESET|AUREON_WM_CS|AUREON_CS8415_CS));
        tmp = snd_ice1712_gpio_read(ice);
        tmp &= ~AUREON_WM_RESET;
        snd_ice1712_gpio_write(ice, tmp);
        udelay(1);
        tmp |= AUREON_WM_CS | AUREON_CS8415_CS;
        snd_ice1712_gpio_write(ice, tmp);
        udelay(1);
        tmp |= AUREON_WM_RESET;
        snd_ice1712_gpio_write(ice, tmp);
        udelay(1);

        /* initialize WM8770 codec */
        for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)
                wm_put(ice, wm_inits[i], wm_inits[i+1]);

        /* initialize CS8415A codec */
        for (i = 0; i < ARRAY_SIZE(cs_inits); i++)
                aureon_spi_write(ice, AUREON_CS8415_CS,
                                 cs_inits[i] | 0x200000, 24);

        snd_ice1712_restore_gpio_status(ice);

        return 0;
}


/*
 * Aureon board don't provide the EEPROM data except for the vendor IDs.
 * hence the driver needs to sets up it properly.
 */

static unsigned char aureon51_eeprom[] __devinitdata = {
        0x12,   /* SYSCONF: clock 512, mpu401, spdif-in/ADC, 3DACs */
        0x80,   /* ACLINK: I2S */
        0xf8,   /* I2S: vol, 96k, 24bit, 192k */
        0xc2,   /* SPDIF: out-en, out-int, spdif-in */
        0xff,   /* GPIO_DIR */
        0xff,   /* GPIO_DIR1 */
        0xbf,   /* GPIO_DIR2 */
        0xff,   /* GPIO_MASK */
        0xff,   /* GPIO_MASK1 */
        0xff,   /* GPIO_MASK2 */
        0x00,   /* GPIO_STATE */
        0x00,   /* GPIO_STATE1 */
        0x00,   /* GPIO_STATE2 */
};

static unsigned char aureon71_eeprom[] __devinitdata = {
        0x13,   /* SYSCONF: clock 512, mpu401, spdif-in/ADC, 4DACs */
        0x80,   /* ACLINK: I2S */
        0xf8,   /* I2S: vol, 96k, 24bit, 192k */
        0xc2,   /* SPDIF: out-en, out-int, spdif-in */
        0xff,   /* GPIO_DIR */
        0xff,   /* GPIO_DIR1 */
        0xbf,   /* GPIO_DIR2 */
        0x00,   /* GPIO_MASK */
        0x00,   /* GPIO_MASK1 */
        0x00,   /* GPIO_MASK2 */
        0x00,   /* GPIO_STATE */
        0x00,   /* GPIO_STATE1 */
        0x00,   /* GPIO_STATE2 */
};

/* entry point */
struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = {
        {
                .subvendor = VT1724_SUBDEVICE_AUREON51_SKY,
                .name = "Terratec Aureon 5.1-Sky",
                .chip_init = aureon_init,
                .build_controls = aureon_add_controls,
                .eeprom_size = sizeof(aureon51_eeprom),
                .eeprom_data = aureon51_eeprom,
        },
        {
                .subvendor = VT1724_SUBDEVICE_AUREON71_SPACE,
                .name = "Terratec Aureon 7.1-Space",
                .chip_init = aureon_init,
                .build_controls = aureon_add_controls,
                .eeprom_size = sizeof(aureon71_eeprom),
                .eeprom_data = aureon71_eeprom,
        },
        { } /* terminator */
};

--- NEW FILE: aureon.h ---
#ifndef __SOUND_AUREON_H
#define __SOUND_AUREON_H

/*
 *   ALSA driver for VIA VT1724 (Envy24HT)
 *
 *   Lowlevel functions for Terratec Aureon cards
 *
 *      Copyright (c) 2003 Takashi Iwai <[EMAIL PROTECTED]>
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 */      

#define  AUREON_DEVICE_DESC            "{Terratec,Aureon 5.1 Sky},"\
                                       "{Terratec,Aureon 7.1 Space},"

#define VT1724_SUBDEVICE_AUREON51_SKY   0x3b154711      /* Aureon 5.1 Sky */
#define VT1724_SUBDEVICE_AUREON71_SPACE 0x3b154511      /* Aureon 7.1 Space */

extern struct snd_ice1712_card_info  snd_vt1724_aureon_cards[];

/* GPIO bits */
#define AUREON_CS8415_CS        (1 << 23)
#define AUREON_CS8415_CDTO      (1 << 22)
#define AUREON_WM_RESET         (1 << 20)
#define AUREON_WM_CLK           (1 << 19)
#define AUREON_WM_DATA          (1 << 18)
#define AUREON_WM_RW            (1 << 17)
#define AUREON_AC97_RESET       (1 << 16)
#define AUREON_DIGITAL_SEL1     (1 << 15)
#define AUREON_HP_SEL           (1 << 14)
#define AUREON_WM_CS            (1 << 12)

#endif /* __SOUND_AUREON_H */

Index: Makefile
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/pci/ice1712/Makefile,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- Makefile    9 May 2003 14:10:36 -0000       1.7
+++ Makefile    4 Jun 2003 12:02:22 -0000       1.8
@@ -4,7 +4,7 @@
 #
 
 snd-ice1712-objs := ice1712.o delta.o hoontech.o ews.o ak4xxx.o
-snd-ice1724-objs := ice1724.o amp.o revo.o ak4xxx.o
+snd-ice1724-objs := ice1724.o amp.o revo.o aureon.o ak4xxx.o
 
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_ICE1712) += snd-ice1712.o

Index: ak4xxx.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/pci/ice1712/ak4xxx.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ak4xxx.c    28 Apr 2003 18:57:23 -0000      1.2
+++ ak4xxx.c    4 Jun 2003 12:02:22 -0000       1.3
@@ -97,17 +97,6 @@
                udelay(1);
        }
 
-       /* save the data */
-       if (ak->type == SND_AK4524 || ak->type == SND_AK4528) {
-               if ((addr != 0x04 && addr != 0x05) || (data & 0x80) == 0)
-                       ak->images[chip][addr] = data;
-               else
-                       ak->ipga_gain[chip][addr-4] = data;
-       } else {
-               /* AK4529, or else */
-               ak->images[chip][addr] = data;
-       }
-       
        if (priv->cs_mask == priv->cs_addr) {
                if (priv->cif) {
                        /* assert a cs pulse to trigger */

Index: ice1712.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/pci/ice1712/ice1712.c,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -r1.30 -r1.31
--- ice1712.c   9 May 2003 14:10:36 -0000       1.30
+++ ice1712.c   4 Jun 2003 12:02:22 -0000       1.31
@@ -298,11 +298,13 @@
 static void snd_ice1712_set_gpio_dir(ice1712_t *ice, unsigned int data)
 {
        snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, data);
+       inb(ICEREG(ice, DATA)); /* dummy read for pci-posting */
 }
 
 static void snd_ice1712_set_gpio_mask(ice1712_t *ice, unsigned int data)
 {
        snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, data);
+       inb(ICEREG(ice, DATA)); /* dummy read for pci-posting */
 }
 
 static unsigned int snd_ice1712_get_gpio_data(ice1712_t *ice)
@@ -313,6 +315,7 @@
 static void snd_ice1712_set_gpio_data(ice1712_t *ice, unsigned int val)
 {
        snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, val);
+       inb(ICEREG(ice, DATA)); /* dummy read for pci-posting */
 }
 
 

Index: ice1724.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/pci/ice1712/ice1724.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- ice1724.c   9 May 2003 14:10:36 -0000       1.10
+++ ice1724.c   4 Jun 2003 12:02:22 -0000       1.11
@@ -42,6 +42,7 @@
 /* lowlevel routines */
 #include "amp.h"
 #include "revo.h"
+#include "aureon.h"
 
 MODULE_AUTHOR("Jaroslav Kysela <[EMAIL PROTECTED]>");
 MODULE_DESCRIPTION("ICEnsemble ICE1724 (Envy24HT)");
@@ -50,6 +51,7 @@
 MODULE_DEVICES("{"
               REVO_DEVICE_DESC
               AMP_AUDIO2000_DEVICE_DESC
+              AUREON_DEVICE_DESC
                "{VIA,VT1724},"
                "{ICEnsemble,Generic ICE1724},"
                "{ICEnsemble,Generic Envy24HT}}");
@@ -172,6 +174,7 @@
 static void snd_vt1724_set_gpio_dir(ice1712_t *ice, unsigned int data)
 {
        outl(data, ICEREG1724(ice, GPIO_DIRECTION));
+       inw(ICEREG1724(ice, GPIO_DIRECTION)); /* dummy read for pci-posting */
 }
 
 /* set the gpio mask (0 = writable) */
@@ -179,12 +182,14 @@
 {
        outw(data, ICEREG1724(ice, GPIO_WRITE_MASK));
        outb((data >> 16) & 0xff, ICEREG1724(ice, GPIO_WRITE_MASK_22));
+       inw(ICEREG1724(ice, GPIO_WRITE_MASK)); /* dummy read for pci-posting */
 }
 
 static void snd_vt1724_set_gpio_data(ice1712_t *ice, unsigned int data)
 {
        outw(data, ICEREG1724(ice, GPIO_DATA));
        outb(data >> 16, ICEREG1724(ice, GPIO_DATA_22));
+       inw(ICEREG1724(ice, GPIO_DATA)); /* dummy read for pci-posting */
 }
 
 static unsigned int snd_vt1724_get_gpio_data(ice1712_t *ice)
@@ -415,14 +420,16 @@
                        val &= ~VT1724_MT_I2S_MCLK_128X; /* 256x MCLK */
                if (val != old) {
                        outb(val, ICEMT1724(ice, I2S_FORMAT));
-                       /* FIXME: is this revo only? */
-                       /* assert PRST# to converters; MT05 bit 7 */
-                       outb(inb(ICEMT1724(ice, AC97_CMD)) | 0x80, ICEMT1724(ice, 
AC97_CMD));
-                       spin_unlock_irqrestore(&ice->reg_lock, flags);
-                       mdelay(5);
-                       spin_lock_irqsave(&ice->reg_lock, flags);
-                       /* deassert PRST# */
-                       outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, 
AC97_CMD));
+                       if (ice->eeprom.subvendor == VT1724_SUBDEVICE_REVOLUTION71) {
+                               /* FIXME: is this revo only? */
+                               /* assert PRST# to converters; MT05 bit 7 */
+                               outb(inb(ICEMT1724(ice, AC97_CMD)) | 0x80, 
ICEMT1724(ice, AC97_CMD));
+                               spin_unlock_irqrestore(&ice->reg_lock, flags);
+                               mdelay(5);
+                               spin_lock_irqsave(&ice->reg_lock, flags);
+                               /* deassert PRST# */
+                               outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, 
ICEMT1724(ice, AC97_CMD));
+                       }
                }
        }
        spin_unlock_irqrestore(&ice->reg_lock, flags);
@@ -1549,6 +1556,7 @@
 static struct snd_ice1712_card_info *card_tables[] __devinitdata = {
        snd_vt1724_revo_cards,
        snd_vt1724_amp_cards, 
+       snd_vt1724_aureon_cards,
        0,
 };
 
@@ -1572,6 +1580,7 @@
 {
        int dev = 0xa0;         /* EEPROM device address */
        unsigned int i, size;
+       struct snd_ice1712_card_info **tbl, *c;
 
        if ((inb(ICEREG1724(ice, I2C_CTRL)) & VT1724_I2C_EEPROM) == 0) {
                snd_printk("ICE1724 has not detected EEPROM\n");
@@ -1581,6 +1590,23 @@
                                (snd_vt1724_read_i2c(ice, dev, 0x01) << 8) | 
                                (snd_vt1724_read_i2c(ice, dev, 0x02) << 16) | 
                                (snd_vt1724_read_i2c(ice, dev, 0x03) << 24);
+
+       /* if the EEPROM is given by the driver, use it */
+       for (tbl = card_tables; *tbl; tbl++) {
+               for (c = *tbl; c->subvendor; c++) {
+                       if (c->subvendor == ice->eeprom.subvendor) {
+                               if (! c->eeprom_size || ! c->eeprom_data)
+                                       goto found;
+                               snd_printdd("using the defined eeprom..\n");
+                               ice->eeprom.version = 2;
+                               ice->eeprom.size = c->eeprom_size + 6;
+                               memcpy(ice->eeprom.data, c->eeprom_data, 
c->eeprom_size);
+                               goto read_skipped;
+                       }
+               }
+       }
+
+ found:
        ice->eeprom.size = snd_vt1724_read_i2c(ice, dev, 0x04);
        if (ice->eeprom.size < 6)
                ice->eeprom.size = 32;
@@ -1597,6 +1623,7 @@
        for (i = 0; i < size; i++)
                ice->eeprom.data[i] = snd_vt1724_read_i2c(ice, dev, i + 6);
 
+ read_skipped:
        ice->eeprom.gpiomask = eeprom_triple(ice, ICE_EEP2_GPIO_MASK);
        ice->eeprom.gpiostate = eeprom_triple(ice, ICE_EEP2_GPIO_STATE);
        ice->eeprom.gpiodir = eeprom_triple(ice, ICE_EEP2_GPIO_DIR);

Index: revo.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/pci/ice1712/revo.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- revo.c      28 Apr 2003 15:17:07 -0000      1.2
+++ revo.c      4 Jun 2003 12:02:22 -0000       1.3
@@ -59,14 +59,14 @@
                reg = 1;
                shift = 3;
        }
-       tmp = ak->images[0][reg];
+       tmp = snd_akm4xxx_get(ak, 0, reg);
        old = (tmp >> shift) & 0x03;
        if (old == dfs)
                return;
 
        /* reset DFS */
        snd_akm4xxx_reset(ak, 1);
-       tmp = ak->images[0][reg];
+       tmp = snd_akm4xxx_get(ak, 0, reg);
        tmp &= ~(0x03 << shift);
        tmp |= dfs << shift;
        snd_akm4xxx_write(ak, 0, reg, tmp);
@@ -121,6 +121,7 @@
 static int __devinit revo_init(ice1712_t *ice)
 {
        akm4xxx_t *ak;
+       int err;
 
        /* determine I2C, DACs and ADCs */
        switch (ice->eeprom.subvendor) {
@@ -139,8 +140,10 @@
        ice->akm_codecs = 2;
        switch (ice->eeprom.subvendor) {
        case VT1724_SUBDEVICE_REVOLUTION71:
-               snd_ice1712_akm4xxx_init(ak, &akm_revo_front, &akm_revo_front_priv, 
ice);
-               snd_ice1712_akm4xxx_init(ak + 1, &akm_revo_surround, 
&akm_revo_surround_priv, ice);
+               if ((err = snd_ice1712_akm4xxx_init(ak, &akm_revo_front, 
&akm_revo_front_priv, ice)) < 0)
+                       return err;
+               if ((err = snd_ice1712_akm4xxx_init(ak + 1, &akm_revo_surround, 
&akm_revo_surround_priv, ice)) < 0)
+                       return err;
                /* unmute all codecs */
                snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, VT1724_REVO_MUTE);
                break;



-------------------------------------------------------
This SF.net email is sponsored by:  Etnus, makers of TotalView, The best
thread debugger on the planet. Designed with thread debugging features
you've never dreamed of, try TotalView 6 free at www.etnus.com.
_______________________________________________
Alsa-cvslog mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-cvslog

Reply via email to