Update of /cvsroot/alsa/alsa-driver/pcmcia/vx
In directory sc8-pr-cvs1:/tmp/cvs-serv4339/pcmcia/vx
Modified Files:
Makefile d563s3_boot.c vx_entry.c vxp440.c vxpocket.c
vxpocket.conf vxpocket.h xilinx_image_vp4.c xilinx_image_vxp.c
Added Files:
vxp440.conf vxp_mixer.c vxp_ops.c
Removed Files:
vx_cmd.c vx_cmd.h vx_core.c vx_irq.c vx_mixer.c vx_pcm.c
vx_uer.c
Log Message:
[Patch: vx-core-in-driver.dif]
- moved VXpocket/VX222 core part into drivers/vx directory.
- the common header vx_core.h in include directory.
- changed the vx-core entry using ops table.
- added vxp440.conf.
--- NEW FILE: vxp440.conf ---
#
# PCMCIA device driver definitions for Digigram VXpocket440 card
#
# put this file under /etc/pcmcia
#
device "snd-vxp440"
class "audio" module "snd-vxp440"
#
# card definitions
#
card "Digigram VX-POCKET440"
manfid 0x01f1, 0x0100
bind "snd-vxp440"
--- NEW FILE: vxp_mixer.c ---
/* to be in alsa-driver-specific code */
#define __NO_VERSION__
/*
* Driver for Digigram VXpocket soundcards
*
* VX-pocket mixer
*
* Copyright (c) 2002 by 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
*/
#include <sound/driver.h>
#include <sound/core.h>
#include <sound/control.h>
#include "vxpocket.h"
#define chip_t vx_core_t
#define MIC_LEVEL_MIN 0
#define MIC_LEVEL_MAX 8
/*
* mic level control (for VXPocket)
*/
static int vx_mic_level_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;
uinfo->value.integer.max = MIC_LEVEL_MAX;
return 0;
}
static int vx_mic_level_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
vx_core_t *_chip = snd_kcontrol_chip(kcontrol);
struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
ucontrol->value.integer.value[0] = chip->mic_level;
return 0;
}
static int vx_mic_level_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
vx_core_t *_chip = snd_kcontrol_chip(kcontrol);
struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
if (chip->mic_level != ucontrol->value.integer.value[0]) {
vx_set_mic_level(_chip, ucontrol->value.integer.value[0]);
chip->mic_level = ucontrol->value.integer.value[0];
return 1;
}
return 0;
}
static snd_kcontrol_new_t vx_control_mic_level = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Mic Capture Volume",
.info = vx_mic_level_info,
.get = vx_mic_level_get,
.put = vx_mic_level_put,
};
/*
* mic boost level control (for VXP440)
*/
static int vx_mic_boost_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
uinfo->count = 1;
uinfo->value.integer.min = 0;
uinfo->value.integer.max = 1;
return 0;
}
static int vx_mic_boost_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
vx_core_t *_chip = snd_kcontrol_chip(kcontrol);
struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
ucontrol->value.integer.value[0] = chip->mic_level;
return 0;
}
static int vx_mic_boost_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
vx_core_t *_chip = snd_kcontrol_chip(kcontrol);
struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
if (chip->mic_level != ucontrol->value.integer.value[0]) {
vx_set_mic_boost(_chip, ucontrol->value.integer.value[0]);
chip->mic_level = ucontrol->value.integer.value[0];
return 1;
}
return 0;
}
static snd_kcontrol_new_t vx_control_mic_boost = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Mic Boost",
.info = vx_mic_boost_info,
.get = vx_mic_boost_get,
.put = vx_mic_boost_put,
};
int vxp_add_mic_controls(vx_core_t *_chip)
{
struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
int err;
/* mute input levels */
chip->mic_level = 0;
switch (_chip->type) {
case VX_TYPE_VXPOCKET:
vx_set_mic_level(_chip, 0);
break;
case VX_TYPE_VXP440:
vx_set_mic_boost(_chip, 0);
break;
}
/* mic level */
switch (_chip->type) {
case VX_TYPE_VXPOCKET:
if ((err = snd_ctl_add(_chip->card,
snd_ctl_new1(&vx_control_mic_level, chip))) < 0)
return err;
break;
case VX_TYPE_VXP440:
if ((err = snd_ctl_add(_chip->card,
snd_ctl_new1(&vx_control_mic_boost, chip))) < 0)
return err;
break;
}
return 0;
}
--- NEW FILE: vxp_ops.c ---
/* to be in alsa-driver-specific code */
#define __NO_VERSION__
/*
* Driver for Digigram VXpocket soundcards
*
* lowlevel routines for VXpocket soundcards
*
* Copyright (c) 2002 by 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
*/
#include <sound/driver.h>
#include <linux/delay.h>
#include <sound/core.h>
#include <asm/io.h>
#include "vxpocket.h"
#define chip_t vx_core_t
static int vxp_reg_offset[VX_REG_MAX] = {
[VX_ICR] = 0x00, // ICR
[VX_CVR] = 0x01, // CVR
[VX_ISR] = 0x02, // ISR
[VX_IVR] = 0x03, // IVR
[VX_RXH] = 0x05, // RXH
[VX_RXM] = 0x06, // RXM
[VX_RXL] = 0x07, // RXL
[VX_DMA] = 0x04, // DMA
[VX_CDSP] = 0x08, // CDSP
[VX_LOFREQ] = 0x09, // LFREQ
[VX_HIFREQ] = 0x0a, // HFREQ
[VX_DATA] = 0x0b, // DATA
[VX_MICRO] = 0x0c, // MICRO
[VX_DIALOG] = 0x0d, // DIALOG
[VX_CSUER] = 0x0e, // CSUER
[VX_RUER] = 0x0f, // RUER
};
inline static unsigned long vxp_reg_addr(vx_core_t *_chip, int reg)
{
struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
return chip->port + vxp_reg_offset[reg];
}
/*
* snd_vx_inb - read a byte from the register
* @offset: register offset
*/
static unsigned char vxp_inb(vx_core_t *chip, int offset)
{
return inb(vxp_reg_addr(chip, offset));
}
/*
* snd_vx_outb - write a byte on the register
* @offset: the register offset
* @val: the value to write
*/
static void vxp_outb(vx_core_t *chip, int offset, unsigned char val)
{
outb(val, vxp_reg_addr(chip, offset));
}
/*
* redefine macros to call directly
*/
#undef vx_inb
#define vx_inb(chip,reg) vxp_inb((vx_core_t*)(chip), VX_##reg)
#undef vx_outb
#define vx_outb(chip,reg,val) vxp_outb((vx_core_t*)(chip), VX_##reg,val)
/*
* vx_check_magic - check the magic word on xilinx
*
* returns zero if a magic word is detected, or a negative error code.
*/
static int vx_check_magic(vx_core_t *chip)
{
long end_time = jiffies + HZ / 5;
int c;
do {
c = vx_inb(chip, CDSP);
if (c == CDSP_MAGIC)
return 0;
snd_vx_delay(chip, 10);
} while (time_after_eq(end_time, jiffies));
snd_printk(KERN_ERR "cannot find xilinx magic word (%x)\n", c);
return -EIO;
}
/*
* vx_test_xilinx - check whether the xilinx is initialized
*
* returns zero if xilinx was already initialized, or a negative error code.
*/
static int vxp_test_xilinx(vx_core_t *chip)
{
chip->xilinx_tested = 1; /* always ok */
return 0;
}
/*
* vx_reset_dsp - reset the DSP
*/
#define XX_DSP_RESET_WAIT_TIME 2 /* ms */
static void vxp_reset_dsp(vx_core_t *_chip)
{
struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
/* set the reset dsp bit to 1 */
vx_outb(chip, CDSP, chip->regCDSP | VXP_CDSP_DSP_RESET_MASK);
mdelay(XX_DSP_RESET_WAIT_TIME);
/* reset the bit */
chip->regCDSP &= ~VXP_CDSP_DSP_RESET_MASK;
vx_outb(chip, CDSP, chip->regCDSP);
mdelay(XX_DSP_RESET_WAIT_TIME);
}
/*
* reset codec bit
*/
static void vxp_reset_codec(vx_core_t *_chip)
{
struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
/* Set the reset CODEC bit to 1. */
vx_outb(chip, CDSP, chip->regCDSP | VXP_CDSP_CODEC_RESET_MASK);
snd_vx_delay(_chip, 10);
/* Set the reset CODEC bit to 0. */
chip->regCDSP &= ~VXP_CDSP_CODEC_RESET_MASK;
vx_outb(chip, CDSP, chip->regCDSP);
snd_vx_delay(_chip, 1);
}
/*
* vx_load_xilinx_binary - load the xilinx binary image
* the binary image is the binary array converted from the bitstream file.
*/
static int vxp_load_xilinx_binary(vx_core_t *_chip)
{
struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
const struct snd_vx_image *xilinx = &_chip->hw->xilinx;
int i, c, err;
int regCSUER, regRUER;
if ((err = vx_check_magic(_chip)) < 0)
return err;
if ((err = snd_vx_load_boot_image(_chip, &_chip->hw->boot)) < 0)
return err;
snd_printdd(KERN_DEBUG "loading xilinx: size = %d\n", xilinx->length);
/* Switch to programmation mode */
chip->regDIALOG |= VXP_DLG_XILINX_REPROG_MASK;
vx_outb(chip, DIALOG, chip->regDIALOG);
/* Save register CSUER and RUER */
regCSUER = vx_inb(chip, CSUER);
regRUER = vx_inb(chip, RUER);
/* reset HF0 and HF1 */
vx_outb(chip, ICR, 0);
/* Wait for answer HF2 equal to 1 */
snd_printdd(KERN_DEBUG "check ISR_HF2\n");
if (vx_check_isr(_chip, ISR_HF2, ISR_HF2, 20) < 0)
goto _error;
/* set HF1 for loading xilinx binary */
vx_outb(chip, ICR, ICR_HF1);
for (i = 0; i < xilinx->length; i++) {
if (vx_wait_isr_bit(_chip, ISR_TX_EMPTY) < 0)
goto _error;
vx_outb(chip, TXL, xilinx->image[i]);
/* wait for reading */
if (vx_wait_for_rx_full(_chip) < 0)
goto _error;
c = vx_inb(chip, RXL);
if (c != xilinx->image[i])
snd_printk(KERN_ERR "vxpocket: load xilinx mismatch at %d:
0x%x != 0x%x\n", i, c, xilinx->image[i]);
}
/* reset HF1 */
vx_outb(chip, ICR, 0);
/* wait for HF3 */
if (vx_check_isr(_chip, ISR_HF3, ISR_HF3, 20) < 0)
goto _error;
/* read the number of bytes received */
if (vx_wait_for_rx_full(_chip) < 0)
goto _error;
c = (int)vx_inb(chip, RXH) << 16;
c |= (int)vx_inb(chip, RXM) << 8;
c |= vx_inb(chip, RXL);
snd_printdd(KERN_DEBUG "xilinx: dsp size received 0x%x, orig 0x%x\n", c,
xilinx->length);
vx_outb(chip, ICR, ICR_HF0);
/* TEMPO 250ms : wait until Xilinx is downloaded */
snd_vx_delay(_chip, 300);
/* test magical word */
if (vx_check_magic(_chip) < 0)
goto _error;
/* Restore register 0x0E and 0x0F (thus replacing COR and FCSR) */
vx_outb(chip, CSUER, regCSUER);
vx_outb(chip, RUER, regRUER);
/* Reset the Xilinx's signal enabling IO access */
chip->regDIALOG |= VXP_DLG_XILINX_REPROG_MASK;
vx_outb(chip, DIALOG, chip->regDIALOG);
snd_vx_delay(_chip, 10);
chip->regDIALOG &= ~VXP_DLG_XILINX_REPROG_MASK;
vx_outb(chip, DIALOG, chip->regDIALOG);
/* Reset of the Codec */
vxp_reset_codec(_chip);
vx_reset_dsp(_chip);
return 0;
_error:
vx_outb(chip, CSUER, regCSUER);
vx_outb(chip, RUER, regRUER);
chip->regDIALOG &= ~VXP_DLG_XILINX_REPROG_MASK;
vx_outb(chip, DIALOG, chip->regDIALOG);
return -EIO;
}
/*
* vx_test_and_ack - test and acknowledge interrupt
*
* called from irq hander, too
*
* spinlock held!
*/
static int vxp_test_and_ack(vx_core_t *_chip)
{
struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
/* not booted yet? */
if (! _chip->xilinx_tested)
return -ENXIO;
if (! (vx_inb(chip, DIALOG) & VXP_DLG_MEMIRQ_MASK))
return -EIO;
/* ok, interrupts generated, now ack it */
/* set ACQUIT bit up and down */
vx_outb(chip, DIALOG, chip->regDIALOG | VXP_DLG_ACK_MEMIRQ_MASK);
/* useless read just to spend some time and maintain
* the ACQUIT signal up for a while ( a bus cycle )
*/
vx_inb(chip, DIALOG);
vx_outb(chip, DIALOG, chip->regDIALOG & ~VXP_DLG_ACK_MEMIRQ_MASK);
return 0;
}
/*
* vx_validate_irq - enable/disable IRQ
*/
static void vxp_validate_irq(vx_core_t *_chip, int enable)
{
struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
/* Set the interrupt enable bit to 1 in CDSP register */
if (enable)
chip->regCDSP |= VXP_CDSP_VALID_IRQ_MASK;
else
chip->regCDSP &= ~VXP_CDSP_VALID_IRQ_MASK;
vx_outb(chip, CDSP, chip->regCDSP);
}
/*
* vx_setup_pseudo_dma - set up the pseudo dma read/write mode.
* @do_write: 0 = read, 1 = set up for DMA write
*/
static void vx_setup_pseudo_dma(vx_core_t *_chip, int do_write)
{
struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
/* Interrupt mode and HREQ pin enabled for host transmit / receive data
transfers */
vx_outb(chip, ICR, do_write ? ICR_TREQ : ICR_RREQ);
/* Reset the pseudo-dma register */
vx_inb(chip, ISR);
vx_outb(chip, ISR, 0);
/* Select DMA in read/write transfer mode and in 16-bit accesses */
chip->regDIALOG |= VXP_DLG_DMA16_SEL_MASK;
chip->regDIALOG |= do_write ? VXP_DLG_DMAWRITE_SEL_MASK :
VXP_DLG_DMAREAD_SEL_MASK;
vx_outb(chip, DIALOG, chip->regDIALOG);
}
/*
* vx_release_pseudo_dma - disable the pseudo-DMA mode
*/
static void vx_release_pseudo_dma(vx_core_t *_chip)
{
struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
/* Disable DMA and 16-bit accesses */
chip->regDIALOG &= ~(VXP_DLG_DMAWRITE_SEL_MASK|
VXP_DLG_DMAREAD_SEL_MASK|
VXP_DLG_DMA16_SEL_MASK);
vx_outb(chip, DIALOG, chip->regDIALOG);
/* HREQ pin disabled. */
vx_outb(chip, ICR, 0);
}
/*
* vx_pseudo_dma_write - write bulk data on pseudo-DMA mode
* @count: data length to transfer in bytes
*
* data size must be aligned to 6 bytes to ensure the 24bit alignment on DSP.
* NB: call with a certain lock!
*/
static void vxp_dma_write(vx_core_t *chip, snd_pcm_runtime_t *runtime,
vx_pipe_t *pipe, int count)
{
long port = vxp_reg_addr(chip, VX_DMA);
int offset = frames_to_bytes(runtime, pipe->hw_ptr);
unsigned short *addr = (unsigned short *)(runtime->dma_area + offset);
vx_setup_pseudo_dma(chip, 1);
if (offset + count > pipe->buffer_bytes) {
int length = pipe->buffer_bytes - offset;
count -= length;
length >>= 1; /* in 16bit words */
/* Transfer using pseudo-dma. */
while (length-- > 0) {
outw(cpu_to_le16(*addr), port);
addr++;
}
addr = (unsigned short *)runtime->dma_area;
pipe->hw_ptr = 0;
}
pipe->hw_ptr += bytes_to_frames(runtime, count);
count >>= 1; /* in 16bit words */
/* Transfer using pseudo-dma. */
while (count-- > 0) {
outw(cpu_to_le16(*addr), port);
addr++;
}
vx_release_pseudo_dma(chip);
}
/*
* vx_pseudo_dma_read - read bulk data on pseudo DMA mode
* @offset: buffer offset in bytes
* @count: data length to transfer in bytes
*
* the read length must be aligned to 6 bytes, as well as write.
* NB: call with a certain lock!
*/
static void vxp_dma_read(vx_core_t *chip, snd_pcm_runtime_t *runtime,
vx_pipe_t *pipe, int count)
{
struct snd_vxpocket *pchip = (struct snd_vxpocket *)chip;
long port = vxp_reg_addr(chip, VX_DMA);
int offset = frames_to_bytes(runtime, pipe->hw_ptr);
unsigned short *addr = (unsigned short *)(runtime->dma_area + offset);
snd_assert(count % 6 == 0, return);
vx_setup_pseudo_dma(chip, 0);
if (offset + count > pipe->buffer_bytes) {
int length = pipe->buffer_bytes - offset;
count -= length;
length >>= 1; /* in 16bit words */
/* Transfer using pseudo-dma. */
while (length-- > 0)
*addr++ = le16_to_cpu(inw(port));
addr = (unsigned short *)runtime->dma_area;
pipe->hw_ptr = 0;
}
pipe->hw_ptr += bytes_to_frames(runtime, count);
count >>= 1; /* in 16bit words */
/* Transfer using pseudo-dma. */
while (count-- > 1)
*addr++ = le16_to_cpu(inw(port));
/* Disable DMA */
pchip->regDIALOG &= ~VXP_DLG_DMAREAD_SEL_MASK;
vx_outb(chip, DIALOG, pchip->regDIALOG);
/* Read the last word (16 bits) */
*addr = le16_to_cpu(inw(port));
/* Disable 16-bit accesses */
pchip->regDIALOG &= ~VXP_DLG_DMA16_SEL_MASK;
vx_outb(chip, DIALOG, pchip->regDIALOG);
/* HREQ pin disabled. */
vx_outb(chip, ICR, 0);
}
/*
* write a codec data (24bit)
*/
static void vxp_write_codec_reg(vx_core_t *chip, int codec, unsigned int data)
{
int i;
/* Activate access to the corresponding codec register */
if (! codec)
vx_inb(chip, LOFREQ);
else
vx_inb(chip, CODEC2);
/* We have to send 24 bits (3 x 8 bits). Start with most signif. Bit */
for (i = 0; i < 24; i++, data <<= 1)
vx_outb(chip, DATA, ((data & 0x800000) ? VX_DATA_CODEC_MASK : 0));
/* Terminate access to codec registers */
vx_inb(chip, HIFREQ);
}
/*
* vx_set_mic_boost - set mic boost level (on vxp440 only)
* @boost: 0 = 20dB, 1 = +38dB
*/
void vx_set_mic_boost(vx_core_t *chip, int boost)
{
struct snd_vxpocket *pchip = (struct snd_vxpocket *)chip;
unsigned long flags;
if (chip->is_stale)
return;
spin_lock_irqsave(&chip->lock, flags);
if (pchip->regCDSP & P24_CDSP_MICS_SEL_MASK) {
if (boost) {
/* boost: 38 dB */
pchip->regCDSP &= ~P24_CDSP_MIC20_SEL_MASK;
pchip->regCDSP |= P24_CDSP_MIC38_SEL_MASK;
} else {
/* minimum value: 20 dB */
pchip->regCDSP |= P24_CDSP_MIC20_SEL_MASK;
pchip->regCDSP &= ~P24_CDSP_MIC38_SEL_MASK;
}
vx_outb(chip, CDSP, pchip->regCDSP);
}
spin_unlock_irqrestore(&chip->lock, flags);
}
/*
* remap the linear value (0-8) to the actual value (0-15)
*/
static int vx_compute_mic_level(int level)
{
switch (level) {
case 5: level = 6 ; break;
case 6: level = 8 ; break;
case 7: level = 11; break;
case 8: level = 15; break;
default: break ;
}
return level;
}
/*
* vx_set_mic_level - set mic level (on vxpocket only)
* @level: the mic level = 0 - 8 (max)
*/
void vx_set_mic_level(vx_core_t *chip, int level)
{
struct snd_vxpocket *pchip = (struct snd_vxpocket *)chip;
unsigned long flags;
if (chip->is_stale)
return;
spin_lock_irqsave(&chip->lock, flags);
if (pchip->regCDSP & VXP_CDSP_MIC_SEL_MASK) {
level = vx_compute_mic_level(level);
vx_outb(chip, MICRO, level);
}
spin_unlock_irqrestore(&chip->lock, flags);
}
/*
* change the input audio source
*/
static void vxp_change_audio_source(vx_core_t *_chip, int src)
{
struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
switch (src) {
case VX_AUDIO_SRC_DIGITAL:
chip->regCDSP |= VXP_CDSP_DATAIN_SEL_MASK;
vx_outb(chip, CDSP, chip->regCDSP);
break;
case VX_AUDIO_SRC_LINE:
chip->regCDSP &= ~VXP_CDSP_DATAIN_SEL_MASK;
if (_chip->type == VX_TYPE_VXP440)
chip->regCDSP &= ~P24_CDSP_MICS_SEL_MASK;
else
chip->regCDSP &= ~VXP_CDSP_MIC_SEL_MASK;
vx_outb(chip, CDSP, chip->regCDSP);
break;
case VX_AUDIO_SRC_MIC:
chip->regCDSP &= ~VXP_CDSP_DATAIN_SEL_MASK;
/* reset mic levels */
if (_chip->type == VX_TYPE_VXP440) {
chip->regCDSP &= ~P24_CDSP_MICS_SEL_MASK;
if (chip->mic_level)
chip->regCDSP |= P24_CDSP_MIC38_SEL_MASK;
else
chip->regCDSP |= P24_CDSP_MIC20_SEL_MASK;
vx_outb(chip, CDSP, chip->regCDSP);
} else {
chip->regCDSP |= VXP_CDSP_MIC_SEL_MASK;
vx_outb(chip, CDSP, chip->regCDSP);
vx_outb(chip, MICRO, vx_compute_mic_level(chip->mic_level));
}
break;
}
}
/*
* change the clock source
* source = INTERNAL_QUARTZ or UER_SYNC
*/
static void vxp_set_clock_source(vx_core_t *_chip, int source)
{
struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
if (source == INTERNAL_QUARTZ)
chip->regCDSP &= ~VXP_CDSP_CLOCKIN_SEL_MASK;
else
chip->regCDSP |= VXP_CDSP_CLOCKIN_SEL_MASK;
vx_outb(chip, CDSP, chip->regCDSP);
}
/*
* reset the board
*/
static void vxp_reset_board(vx_core_t *_chip)
{
struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
chip->regCDSP = 0;
chip->regDIALOG = 0;
}
/*
* callbacks
*/
/* exported */
struct snd_vx_ops snd_vxpocket_ops = {
.in8 = vxp_inb,
.out8 = vxp_outb,
.test_and_ack = vxp_test_and_ack,
.validate_irq = vxp_validate_irq,
.write_codec = vxp_write_codec_reg,
.reset_codec = vxp_reset_codec,
.change_audio_source = vxp_change_audio_source,
.set_clock_source = vxp_set_clock_source,
.test_xilinx = vxp_test_xilinx,
.load_xilinx = vxp_load_xilinx_binary,
.reset_dsp = vxp_reset_dsp,
.reset_board = vxp_reset_board,
.dma_write = vxp_dma_write,
.dma_read = vxp_dma_read,
};
Index: Makefile
===================================================================
RCS file: /cvsroot/alsa/alsa-driver/pcmcia/vx/Makefile,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Makefile 30 Oct 2002 16:44:23 -0000 1.1
+++ Makefile 9 Jan 2003 16:13:16 -0000 1.2
@@ -1,8 +1,5 @@
TOPDIR = ../..
-CONFIG_SND_VXPOCKET=m
-CONFIG_SND_VXP440=m
-
include $(TOPDIR)/toplevel.config
include $(TOPDIR)/Makefile.conf
@@ -12,19 +9,12 @@
TOPDIR = $(MAINSRCDIR)
-export-objs := vx_core.o
-
-# vx_entry.o is included in each card module to avoid the dependency
-# of snd-vxp-lib to pcmcia stuff
-
-snd-vxpocket-objs := vxpocket.o vx_entry.o
-snd-vxp440-objs := vxp440.o vx_entry.o
-snd-vxp-lib-objs := vx_core.o vx_pcm.o vx_mixer.o vx_cmd.o vx_irq.o vx_uer.o
+# export-objs := vx_entry.o
+# snd-vxpocket-lib-objs := vx_entry.o vxp_ops.o vxp_mixer.o
+snd-vxpocket-objs := vxpocket.o vx_entry.o vxp_ops.o vxp_mixer.o
+snd-vxp440-objs := vxp440.o vx_entry.o vxp_ops.o vxp_mixer.o
-obj-$(CONFIG_SND_VXPOCKET) += snd-vxpocket.o snd-vxp-lib.o
-obj-$(CONFIG_SND_VXP440) += snd-vxp440.o snd-vxp-lib.o
+obj-$(CONFIG_SND_VXPOCKET) += snd-vxpocket.o
+obj-$(CONFIG_SND_VXP440) += snd-vxp440.o
include $(TOPDIR)/Rules.make
-
-
-
Index: d563s3_boot.c
===================================================================
RCS file: /cvsroot/alsa/alsa-driver/pcmcia/vx/d563s3_boot.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- d563s3_boot.c 30 Oct 2002 16:44:23 -0000 1.1
+++ d563s3_boot.c 9 Jan 2003 16:13:18 -0000 1.2
@@ -1,66 +1,66 @@
-/*
- * Driver for Digigram VXpocket soundcards
- *
- * Xilinx boot image for VXpocket 440.
- *
- * Copyright (c) 2002 by Digigram S.A.
- *
- * 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
- */
-
-static unsigned char d563s3_boot[504] = {
- 0x00, 0x00, 0xa6, 0x00, 0x00, 0x00, 0x0d, 0x10, 0xc0, 0x00, 0x00, 0x3d,
- 0x0a, 0x82, 0x23, 0x25, 0x00, 0x00, 0x0c, 0xc3, 0x00, 0x00, 0x00, 0x00,
- 0x08, 0x47, 0x06, 0x20, 0xf0, 0x00, 0x05, 0xf4, 0x20, 0xff, 0xff, 0xff,
- 0x0c, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x08, 0x47, 0x06, 0x20, 0xe6, 0x00,
- 0x0c, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x08, 0x47, 0x06, 0x0c, 0xc7, 0xa3,
- 0x00, 0x00, 0x09, 0x0c, 0xc7, 0xa0, 0x00, 0x00, 0x0d, 0x0c, 0xc7, 0xa1,
- 0x00, 0x00, 0x12, 0x0c, 0xc7, 0xa2, 0x00, 0x00, 0x17, 0x05, 0x0c, 0x42,
- 0x06, 0xc6, 0x10, 0x00, 0x00, 0x04, 0x0c, 0xc3, 0x00, 0x00, 0x00, 0x00,
- 0x08, 0x47, 0x06, 0x05, 0x0f, 0xc5, 0x06, 0xc6, 0x10, 0x00, 0x00, 0x05,
- 0x0c, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x08, 0x47, 0x06, 0x47, 0x58, 0x00,
- 0x05, 0x0f, 0x9e, 0x06, 0xc6, 0x10, 0x00, 0x00, 0x05, 0x0c, 0xc3, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x47, 0x06, 0x4f, 0x58, 0x00, 0x05, 0x0f, 0x97,
- 0x0a, 0xc5, 0x60, 0x05, 0x84, 0x04, 0x22, 0x11, 0x00, 0x05, 0xf4, 0x21,
- 0xff, 0xff, 0xff, 0x06, 0xc6, 0x10, 0x00, 0x00, 0x06, 0x0c, 0xc3, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x47, 0x06, 0x07, 0x58, 0x87, 0x00, 0x00, 0x00,
- 0x05, 0x0f, 0x8a, 0x00, 0x03, 0xf8, 0x0a, 0xe1, 0x80, 0x00, 0x00, 0x84,
- 0x20, 0x00, 0x13, 0x08, 0xf4, 0xb9, 0x00, 0x04, 0x39, 0x08, 0xf4, 0xb8,
- 0x00, 0x04, 0x21, 0x0a, 0xfa, 0x6e, 0x08, 0xf4, 0xbd, 0x34, 0x00, 0x08,
- 0x08, 0xf4, 0xbb, 0x01, 0x20, 0x21, 0x08, 0xf4, 0x84, 0x00, 0x10, 0x18,
- 0x0a, 0x84, 0x26, 0x04, 0xcc, 0xdf, 0x07, 0xf4, 0x35, 0x20, 0x10, 0x00,
- 0x07, 0xf4, 0x36, 0x03, 0x30, 0x00, 0x07, 0xf4, 0x34, 0x00, 0xff, 0xff,
- 0x07, 0xf4, 0x33, 0x00, 0xff, 0xff, 0x07, 0xf4, 0x32, 0x00, 0xff, 0xff,
- 0x07, 0xf4, 0x31, 0x00, 0xff, 0xff, 0x07, 0xf4, 0x3d, 0x00, 0x00, 0x00,
- 0x07, 0xf4, 0x3e, 0x00, 0x00, 0x00, 0x07, 0xf4, 0x3f, 0x00, 0x00, 0x3c,
- 0x04, 0xcc, 0xdc, 0x04, 0xcc, 0xcf, 0x07, 0xf4, 0x25, 0x20, 0x10, 0x00,
- 0x07, 0xf4, 0x26, 0x03, 0x30, 0x00, 0x07, 0xf4, 0x24, 0x00, 0xff, 0xff,
- 0x07, 0xf4, 0x23, 0x00, 0xff, 0xff, 0x07, 0xf4, 0x22, 0x00, 0xff, 0xff,
- 0x07, 0xf4, 0x21, 0x00, 0xff, 0xff, 0x07, 0xf4, 0x2d, 0x00, 0x00, 0x01,
- 0x07, 0xf4, 0x2e, 0x00, 0x00, 0x01, 0x07, 0xf4, 0x2f, 0x00, 0x00, 0x3c,
- 0x04, 0xcc, 0xcc, 0x07, 0xf4, 0x1d, 0x00, 0x00, 0x02, 0x07, 0xf4, 0x1e,
- 0x00, 0x00, 0x00, 0x07, 0xf4, 0x1f, 0x00, 0x00, 0x05, 0x07, 0xf4, 0x1b,
- 0x00, 0xc0, 0x00, 0x07, 0xf4, 0x1c, 0x00, 0x01, 0x00, 0x04, 0xcc, 0x83,
- 0x07, 0xf4, 0x0b, 0x00, 0x08, 0x00, 0x07, 0xf4, 0x07, 0x00, 0x08, 0x00,
- 0x05, 0xf4, 0x20, 0xff, 0xff, 0xff, 0x04, 0x64, 0xa0, 0x30, 0x00, 0x00,
- 0x34, 0x00, 0x00, 0x45, 0xf4, 0x00, 0x01, 0x00, 0x00, 0x44, 0xf4, 0x13,
- 0xff, 0xff, 0xff, 0x20, 0x86, 0x00, 0x06, 0xc5, 0x10, 0x00, 0x00, 0x02,
- 0xb0, 0x18, 0x32, 0x0a, 0xbe, 0x20, 0x00, 0x00, 0x00, 0x0a, 0xbe, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x82, 0x22, 0x00, 0xfc, 0xb8,
- 0x60, 0xf4, 0x00, 0x00, 0x00, 0x02, 0x05, 0xf4, 0x20, 0xff, 0xff, 0xff,
- 0x61, 0xf4, 0x00, 0x01, 0x00, 0x00, 0x04, 0x61, 0xa0, 0x44, 0xf4, 0x00,
- 0x00, 0x00, 0x3b, 0x06, 0xc4, 0x10, 0x00, 0x00, 0x04, 0x07, 0xd8, 0x84,
- 0x07, 0x59, 0x84, 0x00, 0x00, 0x00, 0x0a, 0xf0, 0x80, 0x01, 0x00, 0x00,
-};
+/*
+ * Driver for Digigram VXpocket soundcards
+ *
+ * Xilinx boot image for VXpocket V2 and 440.
+ *
+ * Copyright (c) 2002 by Digigram S.A.
+ *
+ * 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
+ */
+
+static unsigned char d563s3_boot[504] = {
+ 0x00, 0x00, 0xa6, 0x00, 0x00, 0x00, 0x0d, 0x10, 0xc0, 0x00, 0x00, 0x3d,
+ 0x0a, 0x82, 0x23, 0x25, 0x00, 0x00, 0x0c, 0xc3, 0x00, 0x00, 0x00, 0x00,
+ 0x08, 0x47, 0x06, 0x20, 0xf0, 0x00, 0x05, 0xf4, 0x20, 0xff, 0xff, 0xff,
+ 0x0c, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x08, 0x47, 0x06, 0x20, 0xe6, 0x00,
+ 0x0c, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x08, 0x47, 0x06, 0x0c, 0xc7, 0xa3,
+ 0x00, 0x00, 0x09, 0x0c, 0xc7, 0xa0, 0x00, 0x00, 0x0d, 0x0c, 0xc7, 0xa1,
+ 0x00, 0x00, 0x12, 0x0c, 0xc7, 0xa2, 0x00, 0x00, 0x17, 0x05, 0x0c, 0x42,
+ 0x06, 0xc6, 0x10, 0x00, 0x00, 0x04, 0x0c, 0xc3, 0x00, 0x00, 0x00, 0x00,
+ 0x08, 0x47, 0x06, 0x05, 0x0f, 0xc5, 0x06, 0xc6, 0x10, 0x00, 0x00, 0x05,
+ 0x0c, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x08, 0x47, 0x06, 0x47, 0x58, 0x00,
+ 0x05, 0x0f, 0x9e, 0x06, 0xc6, 0x10, 0x00, 0x00, 0x05, 0x0c, 0xc3, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x47, 0x06, 0x4f, 0x58, 0x00, 0x05, 0x0f, 0x97,
+ 0x0a, 0xc5, 0x60, 0x05, 0x84, 0x04, 0x22, 0x11, 0x00, 0x05, 0xf4, 0x21,
+ 0xff, 0xff, 0xff, 0x06, 0xc6, 0x10, 0x00, 0x00, 0x06, 0x0c, 0xc3, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x47, 0x06, 0x07, 0x58, 0x87, 0x00, 0x00, 0x00,
+ 0x05, 0x0f, 0x8a, 0x00, 0x03, 0xf8, 0x0a, 0xe1, 0x80, 0x00, 0x00, 0x84,
+ 0x20, 0x00, 0x13, 0x08, 0xf4, 0xb9, 0x00, 0x04, 0x39, 0x08, 0xf4, 0xb8,
+ 0x00, 0x04, 0x21, 0x0a, 0xfa, 0x6e, 0x08, 0xf4, 0xbd, 0x34, 0x00, 0x08,
+ 0x08, 0xf4, 0xbb, 0x01, 0x20, 0x21, 0x08, 0xf4, 0x84, 0x00, 0x10, 0x18,
+ 0x0a, 0x84, 0x26, 0x04, 0xcc, 0xdf, 0x07, 0xf4, 0x35, 0x20, 0x10, 0x00,
+ 0x07, 0xf4, 0x36, 0x03, 0x30, 0x00, 0x07, 0xf4, 0x34, 0x00, 0xff, 0xff,
+ 0x07, 0xf4, 0x33, 0x00, 0xff, 0xff, 0x07, 0xf4, 0x32, 0x00, 0xff, 0xff,
+ 0x07, 0xf4, 0x31, 0x00, 0xff, 0xff, 0x07, 0xf4, 0x3d, 0x00, 0x00, 0x00,
+ 0x07, 0xf4, 0x3e, 0x00, 0x00, 0x00, 0x07, 0xf4, 0x3f, 0x00, 0x00, 0x3c,
+ 0x04, 0xcc, 0xdc, 0x04, 0xcc, 0xcf, 0x07, 0xf4, 0x25, 0x20, 0x10, 0x00,
+ 0x07, 0xf4, 0x26, 0x03, 0x30, 0x00, 0x07, 0xf4, 0x24, 0x00, 0xff, 0xff,
+ 0x07, 0xf4, 0x23, 0x00, 0xff, 0xff, 0x07, 0xf4, 0x22, 0x00, 0xff, 0xff,
+ 0x07, 0xf4, 0x21, 0x00, 0xff, 0xff, 0x07, 0xf4, 0x2d, 0x00, 0x00, 0x01,
+ 0x07, 0xf4, 0x2e, 0x00, 0x00, 0x01, 0x07, 0xf4, 0x2f, 0x00, 0x00, 0x3c,
+ 0x04, 0xcc, 0xcc, 0x07, 0xf4, 0x1d, 0x00, 0x00, 0x02, 0x07, 0xf4, 0x1e,
+ 0x00, 0x00, 0x00, 0x07, 0xf4, 0x1f, 0x00, 0x00, 0x05, 0x07, 0xf4, 0x1b,
+ 0x00, 0xc0, 0x00, 0x07, 0xf4, 0x1c, 0x00, 0x01, 0x00, 0x04, 0xcc, 0x83,
+ 0x07, 0xf4, 0x0b, 0x00, 0x08, 0x00, 0x07, 0xf4, 0x07, 0x00, 0x08, 0x00,
+ 0x05, 0xf4, 0x20, 0xff, 0xff, 0xff, 0x04, 0x64, 0xa0, 0x30, 0x00, 0x00,
+ 0x34, 0x00, 0x00, 0x45, 0xf4, 0x00, 0x01, 0x00, 0x00, 0x44, 0xf4, 0x13,
+ 0xff, 0xff, 0xff, 0x20, 0x86, 0x00, 0x06, 0xc5, 0x10, 0x00, 0x00, 0x02,
+ 0xb0, 0x18, 0x32, 0x0a, 0xbe, 0x20, 0x00, 0x00, 0x00, 0x0a, 0xbe, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x82, 0x22, 0x00, 0xfc, 0xb8,
+ 0x60, 0xf4, 0x00, 0x00, 0x00, 0x02, 0x05, 0xf4, 0x20, 0xff, 0xff, 0xff,
+ 0x61, 0xf4, 0x00, 0x01, 0x00, 0x00, 0x04, 0x61, 0xa0, 0x44, 0xf4, 0x00,
+ 0x00, 0x00, 0x3b, 0x06, 0xc4, 0x10, 0x00, 0x00, 0x04, 0x07, 0xd8, 0x84,
+ 0x07, 0x59, 0x84, 0x00, 0x00, 0x00, 0x0a, 0xf0, 0x80, 0x01, 0x00, 0x00,
+};
Index: vx_entry.c
===================================================================
RCS file: /cvsroot/alsa/alsa-driver/pcmcia/vx/vx_entry.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- vx_entry.c 11 Dec 2002 15:36:33 -0000 1.3
+++ vx_entry.c 9 Jan 2003 16:13:27 -0000 1.4
@@ -1,3 +1,6 @@
+/* to be in alsa-driver-specific code */
+#define __NO_VERSION__
+
/*
* Driver for Digigram VXpocket soundcards
*
@@ -31,33 +34,60 @@
* prototypes
*/
static void vxpocket_config(dev_link_t *link);
-static void vxpocket_release(u_long arg);
static int vxpocket_event(event_t event, int priority, event_callback_args_t *args);
-static void vx_card_free_callback(snd_card_t *card);
/*
- * flush the stale links.
- * the last instances might be left unreleased, so we release now before
- * creating a new one.
+ * print the error message related with cs
*/
-static void flush_stale_links(struct snd_vxp_entry *hw)
+static void cs_error(client_handle_t handle, int func, int ret)
{
- dev_link_t *link, *next;
- for (link = hw->dev_list; link; link = next) {
- next = link->next;
- if (link->state & DEV_STALE_LINK)
- snd_vxpocket_detach(hw ,link);
+ error_info_t err = { func, ret };
+ CardServices(ReportError, handle, &err);
+}
+
+static void vxpocket_release(u_long arg)
+{
+ dev_link_t *link = (dev_link_t *)arg;
+
+ if (link->state & DEV_CONFIG) {
+ /* release cs resources */
+ CardServices(ReleaseConfiguration, link->handle);
+ CardServices(ReleaseIO, link->handle, &link->io);
+ CardServices(ReleaseIRQ, link->handle, &link->irq);
+ link->state &= ~DEV_CONFIG;
}
}
/*
- * print the error message related with cs
+ * destructor
*/
-static void cs_error(client_handle_t handle, int func, int ret)
+static int snd_vxpocket_free(vx_core_t *chip)
{
- error_info_t err = { func, ret };
- CardServices(ReportError, handle, &err);
+ struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
+ struct snd_vxp_entry *hw;
+ dev_link_t *link = &vxp->link;
+
+ vxpocket_release((u_long)link);
+
+ /* Break the link with Card Services */
+ if (link->handle)
+ CardServices(DeregisterClient, link->handle);
+
+ chip->initialized = 0;
+ hw = vxp->hw_entry;
+ if (hw)
+ hw->card_list[vxp->index] = NULL;
+ chip->card = NULL;
+
+ snd_magic_kfree(chip);
+ return 0;
+}
+
+static int snd_vxpocket_dev_free(snd_device_t *device)
+{
+ vx_core_t *chip = snd_magic_cast(vx_core_t, device->device_data, return
+-ENXIO);
+ return snd_vxpocket_free(chip);
}
/*
@@ -69,20 +99,51 @@
client_reg_t client_reg; /* Register with cardmgr */
dev_link_t *link; /* Info for cardmgr */
int i, ret;
- vxpocket_t *chip;
+ vx_core_t *chip;
+ struct snd_vxpocket *vxp;
+ snd_card_t *card;
+ static snd_device_ops_t ops = {
+ .dev_free = snd_vxpocket_dev_free,
+ };
+
+ snd_printdd(KERN_DEBUG "vxpocket_attach called\n");
+ /* find an empty slot from the card list */
+ for (i = 0; i < SNDRV_CARDS; i++) {
+ if (! hw->card_list[i])
+ break;
+ }
+ if (i >= SNDRV_CARDS) {
+ snd_printk(KERN_ERR "vxpocket: too many cards found\n");
+ return NULL;
+ }
+ if (! hw->enable_table[i])
+ return NULL; /* disabled explicitly */
- flush_stale_links(hw);
+ /* ok, create a card instance */
+ card = snd_card_new(hw->index_table[i], hw->id_table[i], THIS_MODULE, 0);
+ if (card == NULL) {
+ snd_printk(KERN_ERR "vxpocket: cannot create a card instance\n");
+ return NULL;
+ }
- chip = snd_vxpocket_create_chip(hw);
+ chip = snd_vx_create(card, hw->hardware, hw->ops,
+ sizeof(struct snd_vxpocket) - sizeof(vx_core_t));
if (! chip)
return NULL;
- chip->card->private_free = vx_card_free_callback;
- link = &chip->link;
- link->priv = chip;
+ if (snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops) < 0) {
+ snd_magic_kfree(chip);
+ snd_card_free(card);
+ return NULL;
+ }
- link->release.function = &vxpocket_release;
- link->release.data = (u_long)link;
+ vxp = (struct snd_vxpocket *)chip;
+ vxp->index = i;
+ vxp->hw_entry = hw;
+ hw->card_list[i] = chip;
+
+ link = &vxp->link;
+ link->priv = chip;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->io.NumPorts1 = 16;
@@ -99,6 +160,9 @@
link->irq.Handler = &snd_vx_irq_handler;
link->irq.Instance = chip;
+ link->release.function = &vxpocket_release;
+ link->release.data = (u_long)link;
+
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
@@ -113,9 +177,12 @@
client_reg.dev_info = hw->dev_info;
client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
+ CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL
+#ifdef CONFIG_PM
+ | CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET
+ | CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME
+#endif
+ ;
client_reg.event_handler = &vxpocket_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
@@ -131,44 +198,73 @@
}
-/*
+/**
+ * snd_vxpocket_assign_resources - initialize the hardware and card instance.
+ * @port: i/o port for the card
+ * @irq: irq number for the card
+ *
+ * this function assigns the specified port and irq, boot the card,
+ * create pcm and control instances, and initialize the rest hardware.
+ *
+ * returns 0 if successful, or a negative error code.
*/
-static void vx_card_free_callback(snd_card_t *card)
+static int snd_vxpocket_assign_resources(vx_core_t *chip, int port, int irq)
{
- vxpocket_t *chip = snd_magic_cast(vxpocket_t, card->private_data, return);
+ int err;
+ snd_card_t *card = chip->card;
+ struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
- if (chip->link.state & DEV_CONFIG)
- vxpocket_release((u_long) &chip->link);
- snd_vxpocket_free_chip(chip);
- snd_magic_kfree(chip);
+ snd_printdd(KERN_DEBUG "vxpocket assign resources: port = 0x%x, irq = %d\n",
+port, irq);
+ vxp->port = port;
+
+ sprintf(card->shortname, "Digigram %s", card->driver);
+ sprintf(card->longname, "%s at 0x%x, irq %i",
+ card->shortname, port, irq);
+
+ if ((err = snd_vx_init(chip)) < 0)
+ return err;
+
+ chip->irq = irq;
+
+ if ((err = snd_vx_pcm_new(chip)) < 0)
+ return err;
+
+ if ((err = snd_vx_mixer_new(chip)) < 0)
+ return err;
+ if ((err = vxp_add_mic_controls(chip)) < 0)
+ return err;
+
+ chip->initialized = 1;
+
+ if ((err = snd_card_register(chip->card)) < 0)
+ return err;
+
+ return 0;
}
+
/*
* snd_vxpocket_detach - detach callback for cs
* @hw: the hardware information
*/
void snd_vxpocket_detach(struct snd_vxp_entry *hw, dev_link_t *link)
{
- dev_link_t **linkp;
- vxpocket_t *chip = snd_magic_cast(vxpocket_t, link->priv, return);
-
- /* Locate device structure */
- for (linkp = &hw->dev_list; *linkp; linkp = &(*linkp)->next)
- if (*linkp == link)
- break;
- if (*linkp == NULL)
- return;
+ vx_core_t *chip = snd_magic_cast(vx_core_t, link->priv, return);
del_timer(&link->release);
- /* Break the link with Card Services */
- if (link->handle)
- CardServices(DeregisterClient, link->handle);
-
+ snd_printdd(KERN_DEBUG "vxpocket_detach called\n");
/* Remove the interface data from the linked list */
- *linkp = link->next;
-
- chip->is_stale = 1;
+ if (hw) {
+ dev_link_t **linkp;
+ /* Locate device structure */
+ for (linkp = &hw->dev_list; *linkp; linkp = &(*linkp)->next)
+ if (*linkp == link)
+ break;
+ if (*linkp)
+ *linkp = link->next;
+ }
+ chip->is_stale = 1; /* to be sure */
snd_card_disconnect(chip->card);
snd_card_free_in_thread(chip->card);
}
@@ -182,7 +278,6 @@
snd_vxpocket_detach(hw, hw->dev_list);
}
-
/*
* configuration callback
*/
@@ -193,12 +288,14 @@
static void vxpocket_config(dev_link_t *link)
{
client_handle_t handle = link->handle;
- vxpocket_t *chip = snd_magic_cast(vxpocket_t, link->priv, return);
+ vx_core_t *chip = snd_magic_cast(vx_core_t, link->priv, return);
+ struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
tuple_t tuple;
cisparse_t parse;
u_short buf[32];
int last_fn, last_ret;
+ snd_printdd(KERN_DEBUG "vxpocket_config called\n");
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
tuple.Attributes = 0;
tuple.TupleData = (cisdata_t *)buf;
@@ -222,29 +319,16 @@
if (snd_vxpocket_assign_resources(chip, link->io.BasePort1,
link->irq.AssignedIRQ) < 0)
goto failed;
- link->dev = &chip->node;
+ link->dev = &vxp->node;
link->state &= ~DEV_CONFIG_PENDING;
return;
cs_failed:
cs_error(link->handle, last_fn, last_ret);
failed:
- vxpocket_release((u_long)link);
-}
-
-
-/*
- * release callback
- */
-static void vxpocket_release(u_long arg)
-{
- dev_link_t *link = (dev_link_t *)arg;
-
CardServices(ReleaseConfiguration, link->handle);
CardServices(ReleaseIO, link->handle, &link->io);
CardServices(ReleaseIRQ, link->handle, &link->irq);
-
- link->state &= ~DEV_CONFIG;
}
@@ -254,44 +338,67 @@
static int vxpocket_event(event_t event, int priority, event_callback_args_t *args)
{
dev_link_t *link = args->client_data;
- vxpocket_t *chip = link->priv;
+ vx_core_t *chip = link->priv;
switch (event) {
case CS_EVENT_CARD_REMOVAL:
+ snd_printdd(KERN_DEBUG "CARD_REMOVAL..\n");
link->state &= ~DEV_PRESENT;
if (link->state & DEV_CONFIG) {
mod_timer(&link->release, jiffies + HZ/20);
- if (chip) {
- chip->is_stale = 1;
- snd_card_disconnect(chip->card);
- snd_card_free_in_thread(chip->card);
- }
+ chip->is_stale = 1;
}
break;
case CS_EVENT_CARD_INSERTION:
+ snd_printdd(KERN_DEBUG "CARD_INSERTION..\n");
link->state |= DEV_PRESENT;
vxpocket_config(link);
break;
+#ifdef CONFIG_PM
case CS_EVENT_PM_SUSPEND:
+ snd_printdd(KERN_DEBUG "SUSPEND\n");
link->state |= DEV_SUSPEND;
- if (chip)
- chip->in_suspend = 1;
+ if (chip) {
+ snd_printdd(KERN_DEBUG "snd_vx_suspend calling\n");
+ snd_vx_suspend(chip);
+ }
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
+ snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n");
if (link->state & DEV_CONFIG)
CardServices(ReleaseConfiguration, link->handle);
break;
case CS_EVENT_PM_RESUME:
+ snd_printdd(KERN_DEBUG "RESUME\n");
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
- if (DEV_OK(link))
+ snd_printdd(KERN_DEBUG "CARD_RESET\n");
+ if (DEV_OK(link)) {
+ //struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
+ snd_printdd(KERN_DEBUG "requestconfig...\n");
CardServices(RequestConfiguration, link->handle, &link->conf);
- if (chip) {
- /* FIXME: call resume... */
- chip->in_suspend = 0;
+ if (chip) {
+ snd_printdd(KERN_DEBUG "calling snd_vx_resume\n");
+ snd_vx_resume(chip);
+ }
}
+ snd_printdd(KERN_DEBUG "resume done!\n");
break;
+#endif
}
return 0;
}
+
+/* we link this module statically with the card modules
+ * due to the pcmcia symbol problems...
+ */
+#if 0
+/*
+ * exported stuffs
+ */
+EXPORT_SYMBOL(snd_vxpocket_ops);
+EXPORT_SYMBOL(snd_vxpocket_attach);
+EXPORT_SYMBOL(snd_vxpocket_detach);
+EXPORT_SYMBOL(snd_vxpocket_detach_all);
+#endif
Index: vxp440.c
===================================================================
RCS file: /cvsroot/alsa/alsa-driver/pcmcia/vx/vxp440.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- vxp440.c 5 Nov 2002 17:11:40 -0000 1.2
+++ vxp440.c 9 Jan 2003 16:13:40 -0000 1.3
@@ -1,153 +1,14 @@
-/*
- * Driver for Digigram VXpocket 440 soundcard
- *
- * Copyright (c) 2002 by 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 COMPILE_VXP440
/*
- * please add the following as /etc/pcmcia/vxpocket.conf:
- *
+ add the following as /etc/pcmcia/vxp440.conf:
- device "snd-vxpocket"
- class "audio" module "snd-vxpocket"
+ device "snd-vxp440"
+ class "audio" module "snd-vxp440"
card "Digigram VX-POCKET440"
manfid 0x01f1, 0x0100
bind "snd-vxp440"
+*/
- */
-
-#include <sound/driver.h>
-#include <sound/core.h>
-#include <pcmcia/version.h>
-#include "vxpocket.h"
-#define SNDRV_GET_ID
-#include <sound/initval.h>
-
-
-/*
- */
-
-MODULE_AUTHOR("Takashi Iwai <[EMAIL PROTECTED]>");
-MODULE_DESCRIPTION("Digigram VXpocket440");
-MODULE_LICENSE("GPL");
-MODULE_CLASSES("{sound}");
-MODULE_DEVICES("{{Digigram,VXpocket440}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */
-static unsigned int irq_mask = 0xffff;
-static int irq_list[4] = { -1 };
-
-MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
-MODULE_PARM_DESC(index, "Index value for VXPocket440 soundcard.");
-MODULE_PARM_SYNTAX(index, SNDRV_INDEX_DESC);
-MODULE_PARM(id, "1-" __MODULE_STRING(SNDRV_CARDS) "s");
-MODULE_PARM_DESC(id, "ID string for VXPocket440 soundcard.");
-MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC);
-MODULE_PARM(enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
-MODULE_PARM_DESC(enable, "Enable VXPocket440 soundcard.");
-MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);
-MODULE_PARM(irq_mask, "i");
-MODULE_PARM_DESC(irq_mask, "IRQ bitmask for VXPocket440 soundcard.");
-MODULE_PARM(irq_list, "1-4i");
-MODULE_PARM_DESC(irq_list, "List of Available interrupts for VXPocket440 soundcard.");
-
-
-/*
- */
-
-#include "xilinx_boot_vp4.c"
-#include "xilinx_image_vp4.c"
-#include "d563s3_boot.c"
-#include "dsp_image_vp4.c"
-
-static dev_info_t dev_info = "snd-vxp440";
-
-static struct snd_vxp_entry hw_entry = {
- .name = "VXPocket440",
- .type = VXP_TYPE_VXP440,
- .dev_info = &dev_info,
-
- /* module parameters */
- .index_table = index,
- .id_table = id,
- .enable_table = enable,
- .irq_mask_p = &irq_mask,
- .irq_list = irq_list,
-
- /* images */
- .boot = { xilinx_boot_vxp440, sizeof(xilinx_boot_vxp440) },
- .xilinx = { xilinx_image_vxp440, sizeof(xilinx_image_vxp440) },
- .dsp_boot = { d563s3_boot, sizeof(d563s3_boot) },
- .dsp = { dsp_image_vxp440, sizeof(dsp_image_vxp440) },
-
- /* hardware specs */
- /* 1 DSP, 1 sync UER, 1 sync World Clock (NIY) */
- /* SMPTE (NIY) */
- /* 2 stereo analog input (line/micro) */
- /* 2 stereo analog output */
- /* Only output levels can be modified */
- /* UER, but only for the first two inputs and outputs. */
- .num_codecs = 2,
- .num_ins = 2,
- .num_outs = 2,
-
-};
-
-/*
- */
-static dev_link_t *vxp_attach(void)
-{
- return snd_vxpocket_attach(&hw_entry);
-}
-
-static void vxp_detach(dev_link_t *link)
-{
- snd_vxpocket_detach(&hw_entry, link);
-}
-
-
-/*
- * Module entry points
- */
-
-static int __init init_vxp440(void)
-{
- servinfo_t serv;
-
- CardServices(GetCardServicesInfo, &serv);
- if (serv.Revision != CS_RELEASE_CODE) {
- printk(KERN_WARNING "init_vxp440: Card Services release does not
match!\n");
- return -1;
- }
- register_pccard_driver(&dev_info, vxp_attach, vxp_detach);
- return 0;
-}
-
-static void __exit exit_vxp440(void)
-{
- unregister_pccard_driver(&dev_info);
- snd_vxpocket_detach_all(&hw_entry);
-}
-
-module_init(init_vxp440);
-module_exit(exit_vxp440);
-
-
-EXPORT_NO_SYMBOLS; /* FIXME: for old kernels */
+#include "vxpocket.c"
Index: vxpocket.c
===================================================================
RCS file: /cvsroot/alsa/alsa-driver/pcmcia/vx/vxpocket.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- vxpocket.c 30 Oct 2002 16:44:23 -0000 1.1
+++ vxpocket.c 9 Jan 2003 16:13:46 -0000 1.2
@@ -1,5 +1,5 @@
/*
- * Driver for Digigram VXpocket soundcard
+ * Driver for Digigram VXpocket V2/440 soundcards
*
* Copyright (c) 2002 by Takashi Iwai <[EMAIL PROTECTED]>
*
@@ -19,9 +19,8 @@
*/
/*
- * please add the following as /etc/pcmcia/vxpocket.conf:
- *
-
+ please add the following as /etc/pcmcia/vxpocket.conf:
+
device "snd-vxpocket"
class "audio" module "snd-vxpocket"
@@ -41,11 +40,17 @@
/*
*/
+#ifdef COMPILE_VXP440
+#define CARD_NAME "VXPocket440"
+#else
+#define CARD_NAME "VXPocket"
+#endif
+
MODULE_AUTHOR("Takashi Iwai <[EMAIL PROTECTED]>");
-MODULE_DESCRIPTION("Digigram VXpocket");
+MODULE_DESCRIPTION("Digigram " CARD_NAME);
MODULE_LICENSE("GPL");
MODULE_CLASSES("{sound}");
-MODULE_DEVICES("{{Digigram,VXpocket}}");
+MODULE_DEVICES("{{Digigram," CARD_NAME "}}");
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
@@ -54,16 +59,16 @@
static int irq_list[4] = { -1 };
MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
-MODULE_PARM_DESC(index, "Index value for VXPocket soundcard.");
+MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
MODULE_PARM_SYNTAX(index, SNDRV_INDEX_DESC);
MODULE_PARM(id, "1-" __MODULE_STRING(SNDRV_CARDS) "s");
-MODULE_PARM_DESC(id, "ID string for VXPocket soundcard.");
+MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC);
MODULE_PARM(enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
-MODULE_PARM_DESC(enable, "Enable VXPocket soundcard.");
+MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);
MODULE_PARM(irq_mask, "i");
-MODULE_PARM_DESC(irq_mask, "IRQ bitmask for VXPocket soundcard.");
+MODULE_PARM_DESC(irq_mask, "IRQ bitmask for " CARD_NAME " soundcard.");
MODULE_PARM(irq_list, "1-4i");
MODULE_PARM_DESC(irq_list, "List of Available interrupts for VXPocket soundcard.");
@@ -71,16 +76,70 @@
/*
*/
+#ifdef COMPILE_VXP440
+/*
+ * VXpocket 440
+ */
+#include "xilinx_boot_vp4.c"
+#include "xilinx_image_vp4.c"
+#include "d563s3_boot.c"
+#include "dsp_image_vp4.c"
+static dev_info_t dev_info = "snd-vxp440";
+
+/* 1 DSP, 1 sync UER, 1 sync World Clock (NIY) */
+/* SMPTE (NIY) */
+/* 2 stereo analog input (line/micro) */
+/* 2 stereo analog output */
+/* Only output levels can be modified */
+/* UER, but only for the first two inputs and outputs. */
+
+#define NUM_CODECS 2
+#define CARD_TYPE VX_TYPE_VXP440
+
+#else
+/*
+ * VXpocket V2
+ */
#include "xilinx_boot_vxp.c"
#include "xilinx_image_vxp.c"
#include "d563s3_boot.c"
#include "dsp_image_vxp.c"
-
static dev_info_t dev_info = "snd-vxpocket";
+/* 1 DSP, 1 sync UER */
+/* 1 programmable clock (NIY) */
+/* 1 stereo analog input (line/micro) */
+/* 1 stereo analog output */
+/* Only output levels can be modified */
+
+#define NUM_CODECS 1
+#define CARD_TYPE VX_TYPE_VXPOCKET
+#endif
+
+
+static struct snd_vx_hardware vxp_hw = {
+ .name = CARD_NAME,
+ .type = CARD_TYPE,
+
+ /* images */
+#ifdef COMPILE_VXP440
+ .boot = { xilinx_boot_vxp440, sizeof(xilinx_boot_vxp440) },
+ .xilinx = { xilinx_image_vxp440, sizeof(xilinx_image_vxp440) },
+ .dsp_boot = { d563s3_boot, sizeof(d563s3_boot) },
+ .dsp = { dsp_image_vxp440, sizeof(dsp_image_vxp440) },
+#else
+ .boot = { xilinx_boot_vxpocket, sizeof(xilinx_boot_vxpocket) },
+ .xilinx = { xilinx_image_vxpocket, sizeof(xilinx_image_vxpocket) },
+ .dsp_boot = { d563s3_boot, sizeof(d563s3_boot) },
+ .dsp = { dsp_image_vxpocket, sizeof(dsp_image_vxpocket) },
+#endif
+ /* hardware specs */
+ .num_codecs = NUM_CODECS,
+ .num_ins = NUM_CODECS,
+ .num_outs = NUM_CODECS,
+};
+
static struct snd_vxp_entry hw_entry = {
- .name = "VXPocket",
- .type = VXP_TYPE_VXPOCKET,
.dev_info = &dev_info,
/* module parameters */
@@ -90,22 +149,9 @@
.irq_mask_p = &irq_mask,
.irq_list = irq_list,
- /* images */
- .boot = { xilinx_boot_vxpocket, sizeof(xilinx_boot_vxpocket) },
- .xilinx = { xilinx_image_vxpocket, sizeof(xilinx_image_vxpocket) },
- .dsp_boot = { d563s3_boot, sizeof(d563s3_boot) },
- .dsp = { dsp_image_vxpocket, sizeof(dsp_image_vxpocket) },
-
- /* hardware specs */
- /* 1 DSP, 1 sync UER */
- /* 1 programmable clock (NIY) */
- /* 1 stereo analog input (line/micro) */
- /* 1 stereo analog output */
- /* Only output levels can be modified */
- .num_codecs = 1,
- .num_ins = 1,
- .num_outs = 1,
-
+ /* h/w config */
+ .hardware = &vxp_hw,
+ .ops = &snd_vxpocket_ops,
};
/*
Index: vxpocket.conf
===================================================================
RCS file: /cvsroot/alsa/alsa-driver/pcmcia/vx/vxpocket.conf,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- vxpocket.conf 5 Nov 2002 17:11:39 -0000 1.2
+++ vxpocket.conf 9 Jan 2003 16:13:46 -0000 1.3
@@ -15,7 +15,3 @@
manfid 0x01f1, 0x0100
bind "snd-vxpocket"
-card "Digigram VX-POCKET440"
- manfid 0x01f1, 0x0100
- bind "snd-vxp440"
-
Index: vxpocket.h
===================================================================
RCS file: /cvsroot/alsa/alsa-driver/pcmcia/vx/vxpocket.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- vxpocket.h 11 Dec 2002 15:36:33 -0000 1.4
+++ vxpocket.h 9 Jan 2003 16:13:47 -0000 1.5
@@ -21,25 +21,14 @@
#ifndef __VXPOCKET_H
#define __VXPOCKET_H
+#include "vx_core.h"
+
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/ds.h>
-typedef struct snd_vxpocket vxpocket_t;
-typedef struct vx_pipe vx_pipe_t;
-
-#define vxpocket_t_magic 0xa15a4101
-#define vx_pipe_t_magic 0xa15a4102
-
-struct snd_vxp_image {
- unsigned char *image;
- unsigned int length;
-};
-
struct snd_vxp_entry {
- const char *name;
- int type; /* VXP_TYPE_XXX */
dev_info_t *dev_info;
/* module parameters */
@@ -49,127 +38,38 @@
unsigned int *irq_mask_p;
int *irq_list;
- /* images */
- struct snd_vxp_image boot;
- struct snd_vxp_image xilinx;
- struct snd_vxp_image dsp_boot;
- struct snd_vxp_image dsp;
-
- /* hardware specs */
- int num_codecs;
- int num_ins;
- int num_outs;
+ /* h/w config */
+ struct snd_vx_hardware *hardware;
+ struct snd_vx_ops *ops;
/* slots */
- vxpocket_t *card_list[SNDRV_CARDS];
+ vx_core_t *card_list[SNDRV_CARDS];
dev_link_t *dev_list; /* Linked list of devices */
};
-/*
- */
-#define SIZE_MAX_CMD 0x10
-#define SIZE_MAX_STATUS 0x10
-
-struct vx_rmh {
- u16 LgCmd; /* length of the command to send (WORDs) */
- u16 LgStat; /* length of the status received (WORDs) */
- u32 Cmd[SIZE_MAX_CMD];
- u32 Stat[SIZE_MAX_STATUS];
- u16 DspStat; /* status type, RMP_SSIZE_XXX */
-};
-
-typedef u64 pcx_time_t;
+struct snd_vxpocket {
-#define VXP_MAX_PIPES 16
-#define VXP_MAX_CODECS 2
+ vx_core_t core;
-#define VXP_MAX_PERIODS 32
+ unsigned long port;
-struct vx_ibl_info {
- int size; /* the current IBL size (0 = query) in bytes */
- int max_size; /* max. IBL size in bytes */
- int min_size; /* min. IBL size in bytes */
- int granularity; /* granularity */
-};
+ int mic_level; /* analog mic level (or boost) */
-struct vx_pipe {
- int number;
- unsigned int is_capture: 1;
- unsigned int data_mode: 1;
- unsigned int running: 1;
- unsigned int prepared: 1;
- int channels;
- unsigned int differed_type;
- pcx_time_t pcx_time;
- snd_pcm_substream_t *substream;
-
- int hbuf_size; /* H-buffer size in bytes */
- int buffer_bytes; /* the ALSA pcm buffer size in bytes */
- int hw_ptr; /* the current hardware pointer in frames */
- int position; /* the current position in frames (playback only) */
- int transferred; /* the transferred size (per period) in frames */
- int chunk_transferred; /* the transferred size (per period) in frames */
- int align; /* size of alignment */
- u64 cur_count; /* current sample position (for playback) */
+ unsigned int regCDSP; /* current CDSP register */
+ unsigned int regDIALOG; /* current DIALOG register */
- struct tasklet_struct start_tq;
-};
+ int index;
+ struct snd_vxp_entry *hw_entry;
-struct snd_vxpocket {
/* pcmcia stuff */
dev_link_t link;
dev_node_t node;
+};
- /* board-speicific entry */
- struct snd_vxp_entry *hw;
-
- /* ALSA stuff */
- snd_card_t *card;
- snd_pcm_t *pcm[VXP_MAX_CODECS];
- snd_info_entry_t *proc_entry;
-
- int index;
- unsigned long port;
- int irq;
+extern struct snd_vx_ops snd_vxpocket_ops;
- spinlock_t lock;
- spinlock_t irq_lock;
- struct tasklet_struct tq;
-
- unsigned int initialized: 1;
- unsigned int in_suspend: 1;
- unsigned int xilinx_tested: 1;
- unsigned int is_stale: 1;
-
- unsigned int pcm_running;
-
- int regCDSP; /* current CDSP register */
- int regDIALOG; /* current DIALOG register */
-
- struct vx_rmh irq_rmh; /* RMH used in interrupts */
-
- unsigned int audio_info; /* see VX_AUDIO_INFO */
- int audio_ins;
- int audio_outs;
- struct vx_pipe **playback_pipes;
- struct vx_pipe **capture_pipes;
-
- int output_level[VXP_MAX_CODECS][2]; /* analog output level */
- int mic_level; /* analog mic level (or boost) */
- int audio_gain[2][4]; /* digital audio level
(playback/capture) */
- unsigned char audio_active[4]; /* mute/unmute on digital playback */
- int audio_monitor[4]; /* playback hw-monitor level */
- unsigned char audio_monitor_active[4]; /* playback hw-monitor mute/unmute */
-
- int audio_source; /* current audio input source */
- int audio_source_target;
- int clock_source; /* current clock source (INTERNAL_QUARTZ or UER_SYNC)
*/
- int freq; /* current frequency */
- int freq_detected; /* detected frequency from digital in */
- int uer_detected; /* VXP_UER_MODE_XXX */
- unsigned int uer_bits; /* IEC958 status bits */
- struct vx_ibl_info ibl; /* IBL information */
-};
+void vx_set_mic_boost(vx_core_t *chip, int boost);
+void vx_set_mic_level(vx_core_t *chip, int level);
/*
* pcmcia stuff
@@ -178,183 +78,8 @@
void snd_vxpocket_detach(struct snd_vxp_entry *hw, dev_link_t *link);
void snd_vxpocket_detach_all(struct snd_vxp_entry *hw);
-/*
- * core constructor/destructor, exported
- */
-vxpocket_t *snd_vxpocket_create_chip(struct snd_vxp_entry *hw);
-void snd_vxpocket_free_chip(vxpocket_t *chip);
-int snd_vxpocket_assign_resources(vxpocket_t *chip, int port, int irq);
-
-/*
- * mixer
- */
-int snd_vxpocket_mixer_new(vxpocket_t *chip);
-
-/*
- * pcm stuff
- */
-int snd_vxpocket_pcm_new(vxpocket_t *chip);
-void vx_pcm_playback_update(vxpocket_t *chip, snd_pcm_substream_t *subs, vx_pipe_t
*pipe);
-void vx_pcm_playback_update_buffer(vxpocket_t *chip, snd_pcm_substream_t *subs,
vx_pipe_t *pipe);
-void vx_pcm_capture_update(vxpocket_t *chip, snd_pcm_substream_t *subs, vx_pipe_t
*pipe);
-
-/*
- * interrupt handler
- */
-void snd_vx_irq_handler(int irq, void *dev, struct pt_regs *regs); /* exported */
-int vx_test_and_ack(vxpocket_t *chip);
-void vx_validate_irq(vxpocket_t *chip, int enable);
-void vx_interrupt(unsigned long private_data);
+int vxp_add_mic_controls(vx_core_t *chip);
-/*
- * lowlevel functions
- */
-void vx_delay(vxpocket_t *chip, int msec);
-int snd_vx_inb(vxpocket_t *chip, int offset);
-void snd_vx_outb(vxpocket_t *chip, int offset, int val);
-#define vx_inb(chip,reg) snd_vx_inb(chip, VXP_##reg)
-#define vx_outb(chip,reg,val) snd_vx_outb(chip, VXP_##reg, val)
-
-int vx_send_msg(vxpocket_t *chip, struct vx_rmh *rmh);
-int vx_send_msg_nolock(vxpocket_t *chip, struct vx_rmh *rmh);
-int vx_send_rih(vxpocket_t *chip, int cmd);
-int vx_send_rih_nolock(vxpocket_t *chip, int cmd);
-
-void vx_reset_codec(vxpocket_t *chip);
-void vx_toggle_dac_mute(vxpocket_t *chip, int mute);
-int vx_sync_audio_source(vxpocket_t *chip);
-void vx_reset_audio_levels(vxpocket_t *chip);
-
-void vx_set_iec958_status(vxpocket_t *chip, unsigned int bits);
-int vx_set_clock(vxpocket_t *chip, int freq);
-void vx_set_internal_clock(vxpocket_t *chip, int freq);
-
-int vx_change_frequency(vxpocket_t *chip);
-
-
-/* error with hardware code,
- * the return value is -(VXP_ERR_MASK | actual-hw-error-code)
- */
-#define VXP_ERR_MASK 0x1000000
-#define vx_get_error(err) (-(err) & ~VXP_ERR_MASK)
-
-
-/*
- * hardware constants
- */
-
-/* hardware type */
-enum {
- VXP_TYPE_VXPOCKET,
- VXP_TYPE_VXP440,
-};
-
-/* audio input source */
-enum {
- VXP_AUDIO_SRC_LINE = 0x00,
- VXP_AUDIO_SRC_MIC = 0x01,
- VXP_AUDIO_SRC_DIGITAL = 0x02,
-};
-
-/* clock source */
-enum {
- INTERNAL_QUARTZ,
- UER_SYNC
-};
-
-/* SPDIF/UER type */
-enum {
- VXP_UER_MODE_CONSUMER,
- VXP_UER_MODE_PROFESSIONAL,
- VXP_UER_MODE_NOT_PRESENT,
-};
-
-/* register offsets */
-enum {
- VXP_ICR = 0x00,
- VXP_CVR = 0x01,
- VXP_ISR = 0x02,
- VXP_IVR = 0x03,
- VXP_DMA = 0x04,
- VXP_RXH = 0x05,
- VXP_RXM = 0x06,
- VXP_RXL = 0x07,
- VXP_TXH = 0x05,
- VXP_TXM = 0x06,
- VXP_TXL = 0x07,
- VXP_CDSP = 0x08,
- VXP_LOFREQ = 0x09,
- VXP_HIFREQ = 0x0a,
- VXP_DATA = 0x0b,
- VXP_MICRO = 0x0c,
- VXP_CODEC2 = VXP_MICRO, /* 2nd codec, VXP440 only */
- VXP_DIALOG = 0x0d,
- VXP_CSUER = 0x0e,
- VXP_RUER = 0x0f,
-};
-
-/* RMH status type */
-enum {
- RMH_SSIZE_FIXED = 0, /* status size given by the driver (in LgStat) */
- RMH_SSIZE_ARG = 1, /* status size given in the LSB byte */
- RMH_SSIZE_MASK = 2, /* status size given in bitmask */
-};
-
-
-/* bits for ICR register */
-#define ICR_HF1 0x10
-#define ICR_HF0 0x08
-#define ICR_TREQ 0x02 /* Interrupt mode + HREQ set on for transfer (->DSP)
request */
-#define ICR_RREQ 0x01 /* Interrupt mode + RREQ set on for transfer (->PC)
request */
-
-/* bits for CVR register */
-#define CVR_HC 0x80
-
-/* bits for ISR register */
-#define ISR_HF3 0x10
-#define ISR_HF2 0x08
-#define ISR_CHK 0x10
-#define ISR_ERR 0x08
-#define ISR_TX_READY 0x04
-#define ISR_TX_EMPTY 0x02
-#define ISR_RX_FULL 0x01
-
-/* bits for audio_info */
-#define VX_AUDIO_INFO_REAL_TIME (1<<0) /* real-time processing available */
-#define VX_AUDIO_INFO_OFFLINE (1<<1) /* offline processing available */
-#define VX_AUDIO_INFO_MPEG1 (1<<5)
-#define VX_AUDIO_INFO_MPEG2 (1<<6)
-#define VX_AUDIO_INFO_LINEAR_8 (1<<7)
-#define VX_AUDIO_INFO_LINEAR_16 (1<<8)
-#define VX_AUDIO_INFO_LINEAR_24 (1<<9)
-
-/* Constants used to access the Codec */
-#define XX_CODEC_SELECTOR 0x20
-/* codec commands */
-#define XX_CODEC_ADC_CONTROL_REGISTER 0x01
-#define XX_CODEC_DAC_CONTROL_REGISTER 0x02
-#define XX_CODEC_LEVEL_LEFT_REGISTER 0x03
-#define XX_CODEC_LEVEL_RIGHT_REGISTER 0x04
-#define XX_CODEC_PORT_MODE_REGISTER 0x05
-#define XX_CODEC_STATUS_REPORT_REGISTER 0x06
-#define XX_CODEC_CLOCK_CONTROL_REGISTER 0x07
-
-/* DSP Interrupt Request values */
-/* add 0x40 offset for vxpocket */
-#define VXP_IRQ_OFFSET 0x40
-/* call with vx_send_irq_dsp() */
-#define IRQ_MESS_WRITE_END 0x30
-#define IRQ_MESS_WRITE_NEXT 0x32
-#define IRQ_MESS_READ_NEXT 0x34
-#define IRQ_MESS_READ_END 0x36
-#define IRQ_MESSAGE 0x38
-#define IRQ_RESET_CHK 0x3A
-#define IRQ_CONNECT_STREAM_NEXT 0x26
-#define IRQ_CONNECT_STREAM_END 0x28
-#define IRQ_PAUSE_START_CONNECT 0x2A
-#define IRQ_END_CONNECTION 0x2C
-
-/* VXPOCKET */
/* Constants used to access the CDSP register (0x08). */
#define CDSP_MAGIC 0xA7 /* magic value (for read) */
/* for write */
@@ -377,14 +102,6 @@
#define P44_MEMIRQ_WCLK_OUT_IN_SEL_MASK 0x02 /* Not used */
#define P44_MEMIRQ_WCLK_UER_SEL_MASK 0x01 /* Not used */
-/* Constants used to access the LOFREQ and HIFREQ registers (0x09 et 0x0A). */
-#define VXP_LOFREQ_VAL(v) ((v) & 0x0000ff)
-#define VXP_HIFREQ_VAL(v) (((v) & 0x000f00)>>8)
-
-/* Constants used to access the DATA register (0x0B). */
-#define VXP_DATA_CODEC_MASK 0x80
-#define VXP_DATA_XICOR_MASK 0x80
-
/* Micro levels (0x0C) */
/* Constants used to access the DIALOG register (0x0D). */
@@ -398,62 +115,6 @@
#define VXP_DLG_MEMIRQ_MASK 0x02 /* R */
#define VXP_DLG_DMA16_SEL_MASK 0x02 /* W */
#define VXP_DLG_ACK_MEMIRQ_MASK 0x01 /* R/W */
-
-/* Constants used to access the CSUER register (0x0E) */
-#define VXP_SUER_FREQ_MASK 0x0C
-#define VXP_SUER_FREQ_32KHz_MASK 0x0C
-#define VXP_SUER_FREQ_44KHz_MASK 0x00
-#define VXP_SUER_FREQ_48KHz_MASK 0x04
-#define VXP_SUER_DATA_PRESENT_MASK 0x02
-#define VXP_SUER_CLOCK_PRESENT_MASK 0x01
-
-#define VXP_CUER_HH_BITC_SEL_MASK 0x00000008 // then read data in RUER
-#define VXP_CUER_MH_BITC_SEL_MASK 0x00000004 // then read data in RUER
-#define VXP_CUER_ML_BITC_SEL_MASK 0x00000002 // then read data in RUER
-#define VXP_CUER_LL_BITC_SEL_MASK 0x00000001 // then read data in RUER
-
-#define XX_UER_CBITS_OFFSET_MASK 0x1F
-
-
-/* Is there async. events pending ( IT Source Test ) */
-#define ASYNC_EVENTS_PENDING 0x008000
-#define HBUFFER_EVENTS_PENDING 0x004000 // Not always accurate
-#define NOTIF_EVENTS_PENDING 0x002000
-#define TIME_CODE_EVENT_PENDING 0x001000
-#define FREQUENCY_CHANGE_EVENT_PENDING 0x000800
-#define END_OF_BUFFER_EVENTS_PENDING 0x000400
-#define FATAL_DSP_ERROR 0xff0000
-
-/* Stream Format Header Defines */
-#define HEADER_FMT_BASE 0xFED00000
-#define HEADER_FMT_MONO 0x000000C0
-#define HEADER_FMT_INTEL 0x00008000
-#define HEADER_FMT_16BITS 0x00002000
-#define HEADER_FMT_24BITS 0x00004000
-#define HEADER_FMT_UPTO11 0x00000200 /* frequency is less or equ.
to 11k.*/
-#define HEADER_FMT_UPTO32 0x00000100 /* frequency is over 11k and
less then 32k.*/
-
-
-/*
- * Audio-level control values
- */
-#define CVAL_M110DB 0x000 /* -110dB */
-#define CVAL_M99DB 0x02C
-#define CVAL_M21DB 0x163
-#define CVAL_M18DB 0x16F
-#define CVAL_M10DB 0x18F
-#define CVAL_0DB 0x1B7
-#define CVAL_18DB 0x1FF /* +18dB */
-#define CVAL_MAX 0x1FF
-
-#define AUDIO_IO_HAS_MUTE_LEVEL 0x400000
-#define AUDIO_IO_HAS_MUTE_MONITORING_1 0x200000
-#define AUDIO_IO_HAS_MUTE_MONITORING_2 0x100000
-#define VALID_AUDIO_IO_DIGITAL_LEVEL 0x01
-#define VALID_AUDIO_IO_MONITORING_LEVEL 0x02
-#define VALID_AUDIO_IO_MUTE_LEVEL 0x04
-#define VALID_AUDIO_IO_MUTE_MONITORING_1 0x08
-#define VALID_AUDIO_IO_MUTE_MONITORING_2 0x10
#endif /* __VXPOCKET_H */
Index: xilinx_image_vp4.c
===================================================================
RCS file: /cvsroot/alsa/alsa-driver/pcmcia/vx/xilinx_image_vp4.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- xilinx_image_vp4.c 30 Oct 2002 16:44:23 -0000 1.1
+++ xilinx_image_vp4.c 9 Jan 2003 16:13:49 -0000 1.2
@@ -20,6 +20,52 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#if 0
+/*
+ * this file was converted from the xilinx bit-stream file
+ * x1_1_vp4.rbt.
+ */
+
+#include <stdio.h>
+
+int main()
+{
+ static char buf[256];
+ int data, c, idx;
+ char *p;
+
+ c = 0;
+ data = 0;
+ idx = 0;
+ while (fgets(buf, sizeof(buf), stdin)) {
+ if (buf[0] != '0' && buf[1] != '1') {
+ fprintf(stderr, "skipping %s", buf);
+ continue;
+ }
+ for (p = buf; *p == '0' || *p == '1'; p++) {
+ data |= (*p - '0') << c;
+ c++;
+ if (c >= 8) {
+ printf("0x%02x,", data);
+ if (idx % 16 == 15)
+ printf("\n");
+ data = 0;
+ c = 0;
+ idx++;
+ }
+ }
+ }
+ if (c) {
+ printf("0x%02x,", data);
+ idx++;
+ }
+ if (idx % 16)
+ printf("\n");
+ fprintf(stderr, "counts = %d\n", idx);
+ return 0;
+}
+#endif
+
static unsigned char xilinx_image_vxp440[22395] = {
0xff,0x04,0xd4,0xbd,0xf8,0xda,0xbf,0xfe,0x7a,0x7f,0xd7,0x9f,0x7e,0xfd,0x7d,0xa7,
0xdf,0x7f,0xdd,0xdd,0xdd,0xd6,0xda,0xed,0xa7,0x5f,0xd7,0xfd,0xed,0xad,0xdf,0x77,
Index: xilinx_image_vxp.c
===================================================================
RCS file: /cvsroot/alsa/alsa-driver/pcmcia/vx/xilinx_image_vxp.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- xilinx_image_vxp.c 30 Oct 2002 16:44:23 -0000 1.1
+++ xilinx_image_vxp.c 9 Jan 2003 16:13:52 -0000 1.2
@@ -20,6 +20,52 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#if 0
+/*
+ * this file was converted from the xilinx bit-stream file
+ * x1_1_vxp.rbt.
+ */
+
+#include <stdio.h>
+
+int main()
+{
+ static char buf[256];
+ int data, c, idx;
+ char *p;
+
+ c = 0;
+ data = 0;
+ idx = 0;
+ while (fgets(buf, sizeof(buf), stdin)) {
+ if (buf[0] != '0' && buf[1] != '1') {
+ fprintf(stderr, "skipping %s", buf);
+ continue;
+ }
+ for (p = buf; *p == '0' || *p == '1'; p++) {
+ data |= (*p - '0') << c;
+ c++;
+ if (c >= 8) {
+ printf("0x%02x,", data);
+ if (idx % 16 == 15)
+ printf("\n");
+ data = 0;
+ c = 0;
+ idx++;
+ }
+ }
+ }
+ if (c) {
+ printf("0x%02x,", data);
+ idx++;
+ }
+ if (idx % 16)
+ printf("\n");
+ fprintf(stderr, "counts = %d\n", idx);
+ return 0;
+}
+#endif
+
static unsigned char xilinx_image_vxpocket[22395] = {
0xff,0x04,0xd4,0xbd,0xf8,0xda,0xbf,0xdf,0x5a,0x7f,0xd7,0x75,0x7f,0x5d,0x7f,0xa7,
0xdf,0x5f,0xfd,0xdd,0x5d,0xd7,0xfa,0xed,0xa7,0x77,0xd7,0xfd,0xed,0xad,0xdf,0x7e,
--- vx_cmd.c DELETED ---
--- vx_cmd.h DELETED ---
--- vx_core.c DELETED ---
--- vx_irq.c DELETED ---
--- vx_mixer.c DELETED ---
--- vx_pcm.c DELETED ---
--- vx_uer.c DELETED ---
-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com
_______________________________________________
Alsa-cvslog mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-cvslog