diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2013-05-03 21:08:42 +0400 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2013-05-03 21:08:42 +0400 |
commit | 1058def8e7827e56ce4a70afb4aeacb5dc44148f (patch) | |
tree | 4495d23e7b54ab5700e3839081e797c1eafe0db9 /kernel/drv/oss_envy24/envy24_6fire.c | |
download | oss4-upstream.tar.gz |
Imported Upstream version 4.2-build2006upstream/4.2-build2006upstream
Diffstat (limited to 'kernel/drv/oss_envy24/envy24_6fire.c')
-rw-r--r-- | kernel/drv/oss_envy24/envy24_6fire.c | 781 |
1 files changed, 781 insertions, 0 deletions
diff --git a/kernel/drv/oss_envy24/envy24_6fire.c b/kernel/drv/oss_envy24/envy24_6fire.c new file mode 100644 index 0000000..469ceab --- /dev/null +++ b/kernel/drv/oss_envy24/envy24_6fire.c @@ -0,0 +1,781 @@ +/* + * Purpose: Card specific routines for Terratec DMX6fire. + */ +/* + * + * This file is part of Open Sound System. + * + * Copyright (C) 4Front Technologies 1996-2008. + * + * This this source file is released under GPL v2 license (no other versions). + * See the COPYING file included in the main directory of this source + * distribution for the license terms and conditions. + * + */ + +#include "oss_config.h" +#include "ac97.h" +#include "envy24.h" + +#if 0 +# define PRT_STATUS(v) outb(v&0xff, 0x378) +#else +# define PRT_STATUS(v) +#endif + +#define DEFAULT_FRONTBOX_SETUP 0xfd + +extern int envy24_gain_sliders; +extern int envy24_virtualout; + +#define EWX_DIG_ADDR 0x24 /* IIC address of digital traceiver chip of 6fire */ + +/*============================================================================= + Function : IIC_GetSDA +------------------------------------------------------------------------------- + Description : + Returns : unsigned char -> + Parameters : unsigned long dwPortAddr -> +------------------------------------------------------------------------------- + Notes : +=============================================================================*/ +static unsigned char +IIC_GetSDA (envy24_devc * devc) +{ + + unsigned char bReg, bSDA; + + /* FMB TEST: RW line */ + /* set write mask */ + bReg = ~(0x08); /* writeable */ + envy24_write_cci (devc, 0x21, bReg); + + /* set RW line LOW */ + bReg = 0; /* writeable */ + envy24_write_cci (devc, 0x20, bReg); + + /* Set direction: SDA to input and SCL to output */ + bReg = envy24_read_cci (devc, 0x22); + bReg |= 0x20; /* SCL output = 1 */ + bReg &= ~0x10; /* SDA input = 0 */ + envy24_write_cci (devc, 0x22, bReg); + + /* Get SDA line state */ + bSDA = envy24_read_cci (devc, 0x20); + + + /* set RW line HIGH */ + bReg = 0x08; /* writeable */ + envy24_write_cci (devc, 0x20, bReg); + + return 1; + /* return ((bSDA & 0x10) == 0x10); */ + +} + +/*============================================================================= + Function : IIC_SetIic +------------------------------------------------------------------------------- + Description : + Returns : void -> + Parameters : unsigned int dwPortAddr -> + : unsigned char fSDA -> + : unsigned char fSCL -> +------------------------------------------------------------------------------- + Notes : +=============================================================================*/ +static void +IIC_SetIic (envy24_devc * devc, unsigned char fSDA, unsigned char fSCL) +{ + unsigned char bReg; + + /* Set direction: SDA and SCL to output */ + bReg = envy24_read_cci (devc, 0x22); + bReg |= (0x20 | 0x10); /* 1 -> output */ + envy24_write_cci (devc, 0x22, bReg); + + /* set write mask */ + bReg = ~(0x20 | 0x10); /* writeable */ + envy24_write_cci (devc, 0x21, bReg); + + /* Set line state */ + /* FMB TEST: RW line */ + bReg = 0x08; + if (fSDA) + bReg += 0x10; + if (fSCL) + bReg += 0x20; + envy24_write_cci (devc, 0x20, bReg); + +} + +/*============================================================================= + Function : IIC_Start +------------------------------------------------------------------------------- + Description : + Returns : void -> + Parameters : unsigned int dwPortAddr -> +------------------------------------------------------------------------------- + Notes : +=============================================================================*/ +/*__inline */ +static void +IIC_Start (envy24_devc * devc) +{ + /* falling edge of SDA while SCL is HIGH */ + IIC_SetIic (devc, 1, 1); + oss_udelay (30); + IIC_SetIic (devc, 0, 1); +} + +/*============================================================================= + Function : IIC_Stop +------------------------------------------------------------------------------- + Description : + Returns : void -> + Parameters : unsigned int dwPortAddr -> +------------------------------------------------------------------------------- + Notes : +=============================================================================*/ +/*__inline */ + +static void +IIC_Stop (envy24_devc * devc) +{ + /* rising edge of SDA while SCL is HIGH */ + IIC_SetIic (devc, 0, 1); + IIC_SetIic (devc, 1, 1); +} + + +/*============================================================================= + Function : IIC_SendByte +------------------------------------------------------------------------------- + Description : + Returns : unsigned char -> + Parameters : unsigned int dwPortAddr -> + : unsigned char bByte -> +------------------------------------------------------------------------------- + Notes : +=============================================================================*/ +/*__inline */ +static unsigned char +IIC_SendByte (envy24_devc * devc, unsigned char bByte) +{ + unsigned char bDataBit, bAck; + int i; + + for (i = 7; i >= 0; i--) /* send byte (MSB first) */ + { + bDataBit = (bByte >> i) & 0x01; + + IIC_SetIic (devc, bDataBit, 0); + IIC_SetIic (devc, bDataBit, 1); + IIC_SetIic (devc, bDataBit, 0); + } /* end for i */ + + IIC_SetIic (devc, 1, 0); + + /* Get acknowledge */ + IIC_SetIic (devc, 1, 1); + bAck = IIC_GetSDA (devc); + /* FMB this is a start condition but never mind */ + IIC_SetIic (devc, 0, 0); +#if 0 + if (bAck) + cmn_err (CE_CONT, "SendByte failed %02x\n", bByte); + else + cmn_err (CE_CONT, "SendByte OK %02x\n", bByte); +#endif + return 1; + /* return (!bAck); *//* bAck = 0 --> success */ +} + +#if 0 +/*============================================================================= + Function : IIC_WriteByte +------------------------------------------------------------------------------- + Description : + Returns : unsigned char -> + Parameters : unsigned int dwPortAddr -> + : unsigned char bIicAddress -> + : unsigned char bByte -> +------------------------------------------------------------------------------- + Notes : +=============================================================================*/ +static unsigned char +IIC_WriteByte (envy24_devc * devc, unsigned char bIicAddress, + unsigned char bByte) +{ + IIC_Start (devc); + + /* send IIC address and data byte */ + if (!IIC_SendByte (devc, bIicAddress)) + { + cmn_err (CE_CONT, "IIC_SendByte 1 failed\n"); + goto FAILED; + } + if (!IIC_SendByte (devc, bByte)) + { + cmn_err (CE_CONT, "IIC_SendByte 2 failed\n"); + goto FAILED; + } + + IIC_Stop (devc); + return 1; + +FAILED: + IIC_Stop (devc); + return 0; +} +#endif + +static unsigned char +IIC_WriteWord (envy24_devc * devc, unsigned char bIicAddress, + unsigned char reg, unsigned char bByte) +{ + IIC_Start (devc); + + /* send IIC address and data byte */ + if (!IIC_SendByte (devc, bIicAddress)) + { + cmn_err (CE_CONT, "IIC_SendByte 1 failed\n"); + goto FAILED; + } + if (!IIC_SendByte (devc, reg)) + { + cmn_err (CE_CONT, "IIC_SendByte 2 failed\n"); + goto FAILED; + } + if (!IIC_SendByte (devc, bByte)) + { + cmn_err (CE_CONT, "IIC_SendByte 3 failed\n"); + goto FAILED; + } + + IIC_Stop (devc); + return 1; + +FAILED: + IIC_Stop (devc); + return 0; +} + +static void +FrontboxControl (envy24_devc * devc, int b) +{ + IIC_WriteWord (devc, 0x40, 0x01, b); /* Output register */ + devc->gpio_tmp = b; +} + +static int +HW_AK4525_SetChipSelect (envy24_devc * devc, unsigned char bCsMask) +{ + unsigned char b; + /* check validity */ + if (bCsMask > 0x07) + { + cmn_err (CE_CONT, "Invalid bCsMask %02x\n", bCsMask); + return 0; /* invalid */ + } + + envy24_write_cci (devc, 0x21, 0x00); + envy24_write_cci (devc, 0x22, 0xff); + b = envy24_read_cci (devc, 0x20); + b &= ~0x07; + + b |= bCsMask & 0x07; + + envy24_write_cci (devc, 0x20, b); + + return 1; +} + +#define HW_AK4525_SetLines IIC_SetIic + +/*============================================================================= + FUNCTION: HW_AK4525_WriteRegister +------------------------------------------------------------------------------- + PURPOSE: + PARAMETERS: unsigned int port - port address for IIC port + unsigned char bCsMask - CoDec bitmask (bits 0..3) + or 0xFF for all codecs together + unsigned char bRegIdx - offset to desired register + unsigned char bReg - new register value + RETURNS: +------------------------------------------------------------------------------- + NOTES: The Chip Selects must have been set prior to this call + PCF8574_CODEC_IIC_ADDRESS + + +-----------------------------------------------------------------+ + | B15 B14 B13 B12 B11 B10 B09 B08|B07 B06 B05 B04 B03 B02 B01 B00 | + +--------+---+-------------------+--------------------------------+ + | C1 C0 |R/W|A4 A3 A2 A1 A0 |D7 D6 D5 D4 D3 D2 D1 D0 | + | 1 0 |1 | <= 7 | data | + +--------+---+-------------------+--------------------------------+ + +=============================================================================*/ +static unsigned char +HW_AK4525_WriteRegister (envy24_devc * devc, unsigned char bCsMask, + unsigned char bRegIdx, unsigned char bRegData) +{ + + unsigned short wCmd; + unsigned char i; + unsigned char fData; + + /* format buffer */ + wCmd = 0xA000 + /* chip address + R/W */ + (((unsigned short) bRegIdx) << 8) + /* register address */ + bRegData; + + HW_AK4525_SetLines (devc, 0, 0); + + /* start write cycle */ + if (!HW_AK4525_SetChipSelect (devc, bCsMask)) + { + cmn_err (CE_CONT, "HW_AK4525_SetChipSelect failed\n"); + return 0; /* = CS to LOW -> data latched */ + } + + + for (i = 0; i < 16; i++) + { + fData = (wCmd & 0x8000) ? 1 : 0; + HW_AK4525_SetLines (devc, fData, 0); + HW_AK4525_SetLines (devc, fData, 1); /* data is clocked in on rising edge of CCLK */ + HW_AK4525_SetLines (devc, fData, 0); + wCmd <<= 1; + } + + /* leave data line HIGH (= default for IIC) */ + HW_AK4525_SetLines (devc, fData, 0); /* data is clocked in on rising edge of CCLK */ + + /* end write cycle */ + if (!HW_AK4525_SetChipSelect (devc, 0x00)) + { + cmn_err (CE_CONT, "HW_AK4525_SetChipSelect 2 failed\n"); + return 0; /* = all CS to HIGH -> CS to default */ + } + + /* default */ + HW_AK4525_SetLines (devc, 1, 1); /* data is clocked in on rising edge of CCLK */ + + return 1; +} + + +/* Register offsets */ +enum +{ + AK4525_REG_POWER, + AK4525_REG_RESET, + AK4525_REG_FORMAT, + AK4525_REG_DEEMPHASIS, + AK4525_REG_LEFT_INPUT, + AK4525_REG_RIGHT_INPUT, + AK4525_REG_LEFT_OUTPUT, + AK4525_REG_RIGHT_OUTPUT +}; + + +/*============================================================================= + Function : HW_AK4525_Reset +------------------------------------------------------------------------------- + Description : + Returns : unsigned char + Parameters : PCUST_HW_INSTANCE_DATA devc - + int nCodecIdx -> 0..3 index of Codec ,-1 -> all +------------------------------------------------------------------------------- + Notes : +=============================================================================*/ +static unsigned char +HW_AK4525_Reset (envy24_devc * devc, int nCodecIdx) +{ + unsigned char bCodecMask = 0; + if (nCodecIdx == -1) + bCodecMask = 0x07; + else + bCodecMask = 0x01 << (nCodecIdx); + + if (!HW_AK4525_WriteRegister (devc, bCodecMask, /* 0x0F -> set mode for all codecs */ + AK4525_REG_RESET, 0x00)) /* DACs,ADCs -> reset */ + { + cmn_err (CE_CONT, "REG_RESET failed\n"); + return 0; + } + + if (!HW_AK4525_WriteRegister (devc, bCodecMask, /* 0x0F -> set mode for all codecs */ + AK4525_REG_FORMAT, 0x60)) /* IIS, 256 fsn, normal speed */ + return 0; + + if (!HW_AK4525_WriteRegister (devc, bCodecMask, /* 0x0F -> set mode for all codecs */ + AK4525_REG_RESET, 0x03)) /* DACs,ADCs -> normal operation */ + return 0; + + if (!HW_AK4525_WriteRegister (devc, bCodecMask, /* 0x0F -> set mode for all codecs */ + AK4525_REG_POWER, 0x07)) /* power on */ + return 0; + + if (!HW_AK4525_WriteRegister (devc, bCodecMask, /* soft mute timeout --> short */ + AK4525_REG_DEEMPHASIS, 0x19)) + return 0; + + if (!HW_AK4525_WriteRegister (devc, + bCodecMask, AK4525_REG_LEFT_INPUT, 0x7f)) + return 0; + + if (!HW_AK4525_WriteRegister (devc, + bCodecMask, AK4525_REG_RIGHT_INPUT, 0x7f)) + return 0; + + if (!HW_AK4525_WriteRegister (devc, + bCodecMask, AK4525_REG_LEFT_OUTPUT, 0x7f)) + return 0; + + if (!HW_AK4525_WriteRegister (devc, + bCodecMask, AK4525_REG_RIGHT_OUTPUT, 0x7f)) + return 0; + + return 1; +} + +static void +set_dmx6fire_speed (envy24_devc * devc) +{ + unsigned char tmp; + + tmp = devc->speedbits; + if (devc->syncsource != SYNC_INTERNAL) + { + tmp |= 0x10; /* S/PDIF input clock select */ + if (devc->model_data->flags & MF_WCLOCK) /* Has world clock too */ + { + int cmd = envy24_read_cci (devc, 0x20); + cmd |= 0x10; /* S/PDIF */ + if (devc->syncsource == SYNC_WCLOCK) + cmd &= ~0x10; /* World clock */ + envy24_write_cci (devc, 0x20, cmd); + } + } + OUTB (devc->osdev, tmp, devc->mt_base + 0x01); +} + +#if 0 +/* + * S/PDIF register access doesn't work so this feature is not enabled. + */ + +#define EWX_CLK 0x20 +#define EWX_DTA 0x10 + +static void +dmx6fire_iic_write_byte (envy24_devc * devc, unsigned char data, + unsigned char save) +{ + int i; + unsigned char gpio; + + for (i = 0; i < 8; i++) + { + int fData = (data & 0x80) ? 1 : 0; + + gpio = 0x08; + if (fData) + gpio |= EWX_DTA; /* DATA */ + envy24_write_cci (devc, 0x20, gpio | save); + envy24_write_cci (devc, 0x20, gpio | EWX_CLK | save); /* Clock pulse */ + envy24_write_cci (devc, 0x20, gpio | save); + + data <<= 1; + } + + envy24_write_cci (devc, 0x20, EWX_DTA | save); + envy24_write_cci (devc, 0x20, EWX_DTA | EWX_CLK | save); /* Clock pulse (ACK) */ + envy24_write_cci (devc, 0x20, EWX_DTA | save); +} + +static unsigned char +dmx6fire_iic_read_byte (envy24_devc * devc, unsigned char save) +{ + int i; + unsigned char data = 0; + int b; + + PRT_STATUS (0x01); + save |= EWX_DTA; + envy24_write_cci (devc, 0x20, save); + oss_udelay (10); +#if 1 + save &= ~8; /* R/W bit */ + envy24_write_cci (devc, 0x22, ~EWX_DTA); /* GPIO direction */ + envy24_write_cci (devc, 0x21, EWX_DTA); /* GPIO write mask */ +#endif + + for (i = 0; i < 8; i++) + { + + envy24_write_cci (devc, 0x20, EWX_CLK | save); /* Clock pulse */ + b = envy24_read_cci (devc, 0x20); + if (b & EWX_DTA) + data |= 0x80; + envy24_write_cci (devc, 0x20, save); + + data >>= 1; + } + + envy24_write_cci (devc, 0x22, 0xff); /* GPIO direction */ + envy24_write_cci (devc, 0x21, 0x00); /* GPIO write mask */ + envy24_write_cci (devc, 0x20, (save & ~EWX_DTA) | 0x08); /* Low for the ACK bit */ + envy24_write_cci (devc, 0x20, (save & ~EWX_DTA) | 0x08 | EWX_CLK); /* Clock for the ACK bit */ + envy24_write_cci (devc, 0x20, save | 0x08); + oss_udelay (10); + return data; +} + +#if 0 +static void +dmx6fire_iic_write (envy24_devc * devc, int addr, + unsigned char bRegIdx, unsigned char bRegData) +{ + unsigned char save; + + /* start write cycle */ + envy24_write_cci (devc, 0x22, 0xff); /* GPIO direction */ + envy24_write_cci (devc, 0x21, 0x00); /* GPIO write mask */ + + save = (envy24_read_cci (devc, 0x20) & ~(EWX_CLK | EWX_DTA)) | 0x08 /* R/W bit */ + ; + /* Send start */ + envy24_write_cci (devc, 0x20, save | EWX_CLK | EWX_DTA); + envy24_write_cci (devc, 0x20, save | EWX_CLK); + envy24_write_cci (devc, 0x20, save); + + dmx6fire_iic_write_byte (devc, addr, save); + dmx6fire_iic_write_byte (devc, bRegIdx, save); + dmx6fire_iic_write_byte (devc, bRegData, save); + + /* Send stop */ + envy24_write_cci (devc, 0x20, save); + envy24_write_cci (devc, 0x20, save | EWX_CLK); + envy24_write_cci (devc, 0x20, save | EWX_CLK | EWX_DTA); +} +#endif + +static unsigned char +dmx6fire_iic_read (envy24_devc * devc, int addr, unsigned char bRegIdx) +{ + unsigned char save, data; + + /* dmx6fire_iic_write(devc, addr, bRegIdx, 0x55); */ + PRT_STATUS (0x80); + + envy24_write_cci (devc, 0x22, 0xff); /* GPIO direction */ + envy24_write_cci (devc, 0x21, 0x00); /* GPIO write mask */ + + save = (envy24_read_cci (devc, 0x20) & ~(EWX_DTA | EWX_CLK)) | 0x08 /* R/W bit */ + ; + PRT_STATUS (0x02); + /* Send start */ + envy24_write_cci (devc, 0x20, save | EWX_CLK | EWX_DTA); + envy24_write_cci (devc, 0x20, save | EWX_CLK); + envy24_write_cci (devc, 0x20, save); + + dmx6fire_iic_write_byte (devc, addr | 0x01, save); + data = dmx6fire_iic_read_byte (devc, save); + + /* Send stop */ + envy24_write_cci (devc, 0x20, save); + envy24_write_cci (devc, 0x20, save | EWX_CLK); + envy24_write_cci (devc, 0x20, save | EWX_CLK | EWX_DTA); + PRT_STATUS (0x00); + return data; +} + +static int +read_dmx6fire_spdif_reg (envy24_devc * devc, int bRegister) +/* +***************************************************************************** +* Reads a byte from a specific CS8427 register. +****************************************************************************/ +{ + + unsigned char ret; + ret = dmx6fire_iic_read (devc, EWX_DIG_ADDR, bRegister); + + return ret; +} + +static void +write_dmx6fire_spdif_reg (envy24_devc * devc, int bRegister, int bData) +{ + + /*dmx6fire_iic_write(devc, EWX_DIG_ADDR, bRegister, bData); */ + IIC_WriteWord (devc, EWX_DIG_ADDR, bRegister, bData); +} +#else +static int +read_dmx6fire_spdif_reg (envy24_devc * devc, int bRegister) +{ + return 0; +} + +static void +write_dmx6fire_spdif_reg (envy24_devc * devc, int bRegister, int bData) +{ +} +#endif + +static void +dmx6fire_card_init (envy24_devc * devc) +{ + envy24_write_cci (devc, 0x20, 0xff); + envy24_write_cci (devc, 0x21, 0x00); + envy24_write_cci (devc, 0x22, 0xff); + envy24_write_cci (devc, 0x20, 0xff); + HW_AK4525_SetChipSelect (devc, 0x00); +#if 1 + + IIC_WriteWord (devc, 0x40, 0x02, 0x00); /* Polarity register */ + IIC_WriteWord (devc, 0x40, 0x03, 0x00); /* Direction register */ + + FrontboxControl (devc, DEFAULT_FRONTBOX_SETUP); /* Set default values */ + + if (!HW_AK4525_Reset (devc, -1)) + cmn_err (CE_CONT, "Envy24: DMX6fire reset failed\n");; +#endif + +} + +static int +dmx6fire_mixer_set (int dev, int ctrl, unsigned int cmd, int value) +{ + envy24_devc *devc = mixer_devs[dev]->devc; + + if (cmd == SNDCTL_MIX_READ) + switch (ctrl) + { + case 1: + if (devc->skipdevs == 2) + return devc->rec_portc[2].riaa_filter; + else + return devc->rec_portc[4].riaa_filter; + break; + + } + + if (cmd == SNDCTL_MIX_WRITE) + switch (ctrl) + { + case 1: + if (devc->skipdevs == 2) + return devc->rec_portc[2].riaa_filter = !!value; + else + return devc->rec_portc[4].riaa_filter = !!value; + break; + + } + + return OSS_EINVAL; +} + +static int +dmx6fire_mix_init (envy24_devc * devc, int dev, int group) +{ + int err; +#if 0 + int i, mask = devc->outportmask, skip, codec, ports; + int range = 3; + int typ = MIXT_ENUM; + if ((group = mixer_ext_create_group (dev, 0, "ENVY24_GAIN")) < 0) + return group; + + skip = devc->skipdevs; + if (skip != 2) + skip = 1; + + if (envy24_gain_sliders) + { + typ = MIXT_MONOSLIDER; + range = 164; + + for (i = 0; i < 0xff; i++) + devc->akm_gains[i] = 0x7f; + } + else + for (i = 0; i < 0xff; i++) + devc->akm_gains[i] = 0; + + for (i = 0; i < 8; i += skip) + { + char tmp[32]; + + if (!(mask & (1 << i))) + continue; /* Not present */ + + if (devc->skipdevs == 2) + { + if (i == 8) + strcpy (tmp, "ENVY24_SPDOUT"); + else + sprintf (tmp, "ENVY24_OUT%d/%d", i + 1, i + 2); + + codec = (i > 1) ? AKM_B : AKM_A; + ports = 0x0c; /* Both output ports */ + if ((err = mixer_ext_create_control (dev, group, + codec | ports, envy24_set_tdif, + typ, + tmp, range, + MIXF_MAINVOL | + MIXF_READABLE | + MIXF_WRITEABLE)) < 0) + return err; + } + else + { + if (i == 8) + strcpy (tmp, "ENVY24_SPDOUTL"); + else if (i == 9) + strcpy (tmp, "ENVY24_SPDOUTR"); + else + sprintf (tmp, "ENVY24_OUT%d", i + 1); + + codec = (i > 1) ? AKM_B : AKM_A; + ports = (i & 1) ? 0x08 : 0x04; + if ((err = mixer_ext_create_control (dev, group, + codec | ports, envy24_set_tdif, + typ, + tmp, range, + MIXF_MAINVOL | + MIXF_READABLE | + MIXF_WRITEABLE)) < 0) + return err; + } + } +#endif + + if ((group = mixer_ext_create_group (dev, 0, "ENVY24_6FIRE")) < 0) + return group; + + if ((err = mixer_ext_create_control (dev, group, + 1, dmx6fire_mixer_set, + MIXT_ONOFF, + "6FIRE_RIAA", 2, + MIXF_READABLE | MIXF_WRITEABLE)) < 0) + return err; + + return 0; +} + +envy24_auxdrv_t dmx6fire_auxdrv = { + dmx6fire_card_init, + dmx6fire_mix_init, + init_cs8427_spdif, + write_cs8427_spdif, + NULL, + read_dmx6fire_spdif_reg, + write_dmx6fire_spdif_reg, + set_dmx6fire_speed, + NULL, + cs8427_spdif_mixer_init +}; |