⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 riptide.c

📁 LINUX 2.6.17.4的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *   Driver for the Conexant Riptide Soundchip * *	Copyright (c) 2004 Peter Gruber <nokos@gmx.net> * *   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 * *//*  History:   - 02/15/2004 first release     This Driver is based on the OSS Driver version from Linuxant (riptide-0.6lnxtbeta03111100)  credits from the original files:    MODULE NAME:        cnxt_rt.h                         AUTHOR:             K. Lazarev  (Transcribed by KNL)  HISTORY:         Major Revision               Date        By            -----------------------------     --------     -----            Created                           02/1/2000     KNL  MODULE NAME:     int_mdl.c                         AUTHOR:          Konstantin Lazarev    (Transcribed by KNL)  HISTORY:         Major Revision               Date        By            -----------------------------     --------     -----            Created                           10/01/99      KNL	      MODULE NAME:        riptide.h                         AUTHOR:             O. Druzhinin  (Transcribed by OLD)  HISTORY:         Major Revision               Date        By            -----------------------------     --------     -----            Created                           10/16/97      OLD  MODULE NAME:        Rp_Cmdif.cpp                         AUTHOR:             O. Druzhinin  (Transcribed by OLD)                      K. Lazarev    (Transcribed by KNL)  HISTORY:         Major Revision               Date        By            -----------------------------     --------     -----            Adopted from NT4 driver            6/22/99      OLD            Ported to Linux                    9/01/99      KNL  MODULE NAME:        rt_hw.c                         AUTHOR:             O. Druzhinin  (Transcribed by OLD)                      C. Lazarev    (Transcribed by CNL)  HISTORY:         Major Revision               Date        By            -----------------------------     --------     -----            Created                           11/18/97      OLD            Hardware functions for RipTide    11/24/97      CNL            (ES1) are coded            Hardware functions for RipTide    12/24/97      CNL            (A0) are coded            Hardware functions for RipTide    03/20/98      CNL            (A1) are coded            Boot loader is included           05/07/98      CNL            Redesigned for WDM                07/27/98      CNL            Redesigned for Linux              09/01/99      CNL  MODULE NAME:        rt_hw.h  AUTHOR:             C. Lazarev    (Transcribed by CNL)  HISTORY:         Major Revision               Date        By            -----------------------------     --------     -----            Created                           11/18/97      CNL  MODULE NAME:     rt_mdl.c                         AUTHOR:          Konstantin Lazarev    (Transcribed by KNL)  HISTORY:         Major Revision               Date        By            -----------------------------     --------     -----            Created                           10/01/99      KNL  MODULE NAME:        mixer.h                          AUTHOR:             K. Kenney  HISTORY:         Major Revision                   Date          By            -----------------------------          --------     -----            Created from MS W95 Sample             11/28/95      KRS            RipTide                                10/15/97      KRS            Adopted for Windows NT driver          01/20/98      CNL*/#include <sound/driver.h>#include <linux/delay.h>#include <linux/init.h>#include <linux/interrupt.h>#include <linux/pci.h>#include <linux/slab.h>#include <linux/wait.h>#include <linux/gameport.h>#include <linux/device.h>#include <linux/firmware.h>#include <asm/io.h>#include <sound/core.h>#include <sound/info.h>#include <sound/control.h>#include <sound/pcm.h>#include <sound/pcm_params.h>#include <sound/ac97_codec.h>#include <sound/mpu401.h>#include <sound/opl3.h>#include <sound/initval.h>#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))#define SUPPORT_JOYSTICK 1#endifMODULE_AUTHOR("Peter Gruber <nokos@gmx.net>");MODULE_DESCRIPTION("riptide");MODULE_LICENSE("GPL");MODULE_SUPPORTED_DEVICE("{{Conexant,Riptide}}");static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;#ifdef SUPPORT_JOYSTICKstatic int joystick_port[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS - 1)] = 0x200 };#endifstatic int mpu_port[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS - 1)] = 0x330 };static int opl3_port[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS - 1)] = 0x388 };module_param_array(index, int, NULL, 0444);MODULE_PARM_DESC(index, "Index value for Riptide soundcard.");module_param_array(id, charp, NULL, 0444);MODULE_PARM_DESC(id, "ID string for Riptide soundcard.");module_param_array(enable, bool, NULL, 0444);MODULE_PARM_DESC(enable, "Enable Riptide soundcard.");#ifdef SUPPORT_JOYSTICKmodule_param_array(joystick_port, int, NULL, 0444);MODULE_PARM_DESC(joystick_port, "Joystick port # for Riptide soundcard.");#endifmodule_param_array(mpu_port, int, NULL, 0444);MODULE_PARM_DESC(mpu_port, "MPU401 port # for Riptide driver.");module_param_array(opl3_port, int, NULL, 0444);MODULE_PARM_DESC(opl3_port, "OPL3 port # for Riptide driver.");/* */#define MPU401_HW_RIPTIDE MPU401_HW_MPU401#define OPL3_HW_RIPTIDE   OPL3_HW_OPL3#define PCI_EXT_CapId       0x40#define PCI_EXT_NextCapPrt  0x41#define PCI_EXT_PWMC        0x42#define PCI_EXT_PWSCR       0x44#define PCI_EXT_Data00      0x46#define PCI_EXT_PMSCR_BSE   0x47#define PCI_EXT_SB_Base     0x48#define PCI_EXT_FM_Base     0x4a#define PCI_EXT_MPU_Base    0x4C#define PCI_EXT_Game_Base   0x4E#define PCI_EXT_Legacy_Mask 0x50#define PCI_EXT_AsicRev     0x52#define PCI_EXT_Reserved3   0x53#define LEGACY_ENABLE_ALL      0x8000	/* legacy device options */#define LEGACY_ENABLE_SB       0x4000#define LEGACY_ENABLE_FM       0x2000#define LEGACY_ENABLE_MPU_INT  0x1000#define LEGACY_ENABLE_MPU      0x0800#define LEGACY_ENABLE_GAMEPORT 0x0400#define MAX_WRITE_RETRY  10	/* cmd interface limits */#define MAX_ERROR_COUNT  10#define CMDIF_TIMEOUT    500000#define RESET_TRIES      5#define READ_PORT_ULONG(p)     inl((unsigned long)&(p))#define WRITE_PORT_ULONG(p,x)  outl(x,(unsigned long)&(p))#define READ_AUDIO_CONTROL(p)     READ_PORT_ULONG(p->audio_control)#define WRITE_AUDIO_CONTROL(p,x)  WRITE_PORT_ULONG(p->audio_control,x)#define UMASK_AUDIO_CONTROL(p,x)  WRITE_PORT_ULONG(p->audio_control,READ_PORT_ULONG(p->audio_control)|x)#define MASK_AUDIO_CONTROL(p,x)   WRITE_PORT_ULONG(p->audio_control,READ_PORT_ULONG(p->audio_control)&x)#define READ_AUDIO_STATUS(p)      READ_PORT_ULONG(p->audio_status)#define SET_GRESET(p)     UMASK_AUDIO_CONTROL(p,0x0001)	/* global reset switch */#define UNSET_GRESET(p)   MASK_AUDIO_CONTROL(p,~0x0001)#define SET_AIE(p)        UMASK_AUDIO_CONTROL(p,0x0004)	/* interrupt enable */#define UNSET_AIE(p)      MASK_AUDIO_CONTROL(p,~0x0004)#define SET_AIACK(p)      UMASK_AUDIO_CONTROL(p,0x0008)	/* interrupt acknowledge */#define UNSET_AIACKT(p)   MASKAUDIO_CONTROL(p,~0x0008)#define SET_ECMDAE(p)     UMASK_AUDIO_CONTROL(p,0x0010)#define UNSET_ECMDAE(p)   MASK_AUDIO_CONTROL(p,~0x0010)#define SET_ECMDBE(p)     UMASK_AUDIO_CONTROL(p,0x0020)#define UNSET_ECMDBE(p)   MASK_AUDIO_CONTROL(p,~0x0020)#define SET_EDATAF(p)     UMASK_AUDIO_CONTROL(p,0x0040)#define UNSET_EDATAF(p)   MASK_AUDIO_CONTROL(p,~0x0040)#define SET_EDATBF(p)     UMASK_AUDIO_CONTROL(p,0x0080)#define UNSET_EDATBF(p)   MASK_AUDIO_CONTROL(p,~0x0080)#define SET_ESBIRQON(p)   UMASK_AUDIO_CONTROL(p,0x0100)#define UNSET_ESBIRQON(p) MASK_AUDIO_CONTROL(p,~0x0100)#define SET_EMPUIRQ(p)    UMASK_AUDIO_CONTROL(p,0x0200)#define UNSET_EMPUIRQ(p)  MASK_AUDIO_CONTROL(p,~0x0200)#define IS_CMDE(a)        (READ_PORT_ULONG(a->stat)&0x1)	/* cmd empty */#define IS_DATF(a)        (READ_PORT_ULONG(a->stat)&0x2)	/* data filled */#define IS_READY(p)       (READ_AUDIO_STATUS(p)&0x0001)#define IS_DLREADY(p)     (READ_AUDIO_STATUS(p)&0x0002)#define IS_DLERR(p)       (READ_AUDIO_STATUS(p)&0x0004)#define IS_GERR(p)        (READ_AUDIO_STATUS(p)&0x0008)	/* error ! */#define IS_CMDAEIRQ(p)    (READ_AUDIO_STATUS(p)&0x0010)#define IS_CMDBEIRQ(p)    (READ_AUDIO_STATUS(p)&0x0020)#define IS_DATAFIRQ(p)    (READ_AUDIO_STATUS(p)&0x0040)#define IS_DATBFIRQ(p)    (READ_AUDIO_STATUS(p)&0x0080)#define IS_EOBIRQ(p)      (READ_AUDIO_STATUS(p)&0x0100)	/* interrupt status */#define IS_EOSIRQ(p)      (READ_AUDIO_STATUS(p)&0x0200)#define IS_EOCIRQ(p)      (READ_AUDIO_STATUS(p)&0x0400)#define IS_UNSLIRQ(p)     (READ_AUDIO_STATUS(p)&0x0800)#define IS_SBIRQ(p)       (READ_AUDIO_STATUS(p)&0x1000)#define IS_MPUIRQ(p)      (READ_AUDIO_STATUS(p)&0x2000)#define RESP 0x00000001		/* command flags */#define PARM 0x00000002#define CMDA 0x00000004#define CMDB 0x00000008#define NILL 0x00000000#define LONG0(a)   ((u32)a)	/* shifts and masks */#define BYTE0(a)   (LONG0(a)&0xff)#define BYTE1(a)   (BYTE0(a)<<8)#define BYTE2(a)   (BYTE0(a)<<16)#define BYTE3(a)   (BYTE0(a)<<24)#define WORD0(a)   (LONG0(a)&0xffff)#define WORD1(a)   (WORD0(a)<<8)#define WORD2(a)   (WORD0(a)<<16)#define TRINIB0(a) (LONG0(a)&0xffffff)#define TRINIB1(a) (TRINIB0(a)<<8)#define RET(a)     ((union cmdret *)(a))#define SEND_GETV(p,b)             sendcmd(p,RESP,GETV,0,RET(b))	/* get version */#define SEND_GETC(p,b,c)           sendcmd(p,PARM|RESP,GETC,c,RET(b))#define SEND_GUNS(p,b)             sendcmd(p,RESP,GUNS,0,RET(b))#define SEND_SCID(p,b)             sendcmd(p,RESP,SCID,0,RET(b))#define SEND_RMEM(p,b,c,d)         sendcmd(p,PARM|RESP,RMEM|BYTE1(b),LONG0(c),RET(d))	/* memory access for firmware write */#define SEND_SMEM(p,b,c)           sendcmd(p,PARM,SMEM|BYTE1(b),LONG0(c),RET(0))	/* memory access for firmware write */#define SEND_WMEM(p,b,c)           sendcmd(p,PARM,WMEM|BYTE1(b),LONG0(c),RET(0))	/* memory access for firmware write */#define SEND_SDTM(p,b,c)           sendcmd(p,PARM|RESP,SDTM|TRINIB1(b),0,RET(c))	/* memory access for firmware write */#define SEND_GOTO(p,b)             sendcmd(p,PARM,GOTO,LONG0(b),RET(0))	/* memory access for firmware write */#define SEND_SETDPLL(p)	           sendcmd(p,0,ARM_SETDPLL,0,RET(0))#define SEND_SSTR(p,b,c)           sendcmd(p,PARM,SSTR|BYTE3(b),LONG0(c),RET(0))	/* start stream */#define SEND_PSTR(p,b)             sendcmd(p,PARM,PSTR,BYTE3(b),RET(0))	/* pause stream */#define SEND_KSTR(p,b)             sendcmd(p,PARM,KSTR,BYTE3(b),RET(0))	/* stop stream */#define SEND_KDMA(p)               sendcmd(p,0,KDMA,0,RET(0))	/* stop all dma */#define SEND_GPOS(p,b,c,d)         sendcmd(p,PARM|RESP,GPOS,BYTE3(c)|BYTE2(b),RET(d))	/* get position in dma */#define SEND_SETF(p,b,c,d,e,f,g)   sendcmd(p,PARM,SETF|WORD1(b)|BYTE3(c),d|BYTE1(e)|BYTE2(f)|BYTE3(g),RET(0))	/* set sample format at mixer */#define SEND_GSTS(p,b,c,d)         sendcmd(p,PARM|RESP,GSTS,BYTE3(c)|BYTE2(b),RET(d))#define SEND_NGPOS(p,b,c,d)        sendcmd(p,PARM|RESP,NGPOS,BYTE3(c)|BYTE2(b),RET(d))#define SEND_PSEL(p,b,c)           sendcmd(p,PARM,PSEL,BYTE2(b)|BYTE3(c),RET(0))	/* activate lbus path */#define SEND_PCLR(p,b,c)           sendcmd(p,PARM,PCLR,BYTE2(b)|BYTE3(c),RET(0))	/* deactivate lbus path */#define SEND_PLST(p,b)             sendcmd(p,PARM,PLST,BYTE3(b),RET(0))#define SEND_RSSV(p,b,c,d)         sendcmd(p,PARM|RESP,RSSV,BYTE2(b)|BYTE3(c),RET(d))#define SEND_LSEL(p,b,c,d,e,f,g,h) sendcmd(p,PARM,LSEL|BYTE1(b)|BYTE2(c)|BYTE3(d),BYTE0(e)|BYTE1(f)|BYTE2(g)|BYTE3(h),RET(0))	/* select paths for internal connections */#define SEND_SSRC(p,b,c,d,e)       sendcmd(p,PARM,SSRC|BYTE1(b)|WORD2(c),WORD0(d)|WORD2(e),RET(0))	/* configure source */#define SEND_SLST(p,b)             sendcmd(p,PARM,SLST,BYTE3(b),RET(0))#define SEND_RSRC(p,b,c)           sendcmd(p,RESP,RSRC|BYTE1(b),0,RET(c))	/* read source config */#define SEND_SSRB(p,b,c)           sendcmd(p,PARM,SSRB|BYTE1(b),WORD2(c),RET(0))#define SEND_SDGV(p,b,c,d,e)       sendcmd(p,PARM,SDGV|BYTE2(b)|BYTE3(c),WORD0(d)|WORD2(e),RET(0))	/* set digital mixer */#define SEND_RDGV(p,b,c,d)         sendcmd(p,PARM|RESP,RDGV|BYTE2(b)|BYTE3(c),0,RET(d))	/* read digital mixer */#define SEND_DLST(p,b)             sendcmd(p,PARM,DLST,BYTE3(b),RET(0))#define SEND_SACR(p,b,c)           sendcmd(p,PARM,SACR,WORD0(b)|WORD2(c),RET(0))	/* set AC97 register */#define SEND_RACR(p,b,c)           sendcmd(p,PARM|RESP,RACR,WORD2(b),RET(c))	/* get AC97 register */#define SEND_ALST(p,b)             sendcmd(p,PARM,ALST,BYTE3(b),RET(0))#define SEND_TXAC(p,b,c,d,e,f)     sendcmd(p,PARM,TXAC|BYTE1(b)|WORD2(c),WORD0(d)|BYTE2(e)|BYTE3(f),RET(0))#define SEND_RXAC(p,b,c,d)         sendcmd(p,PARM|RESP,RXAC,BYTE2(b)|BYTE3(c),RET(d))#define SEND_SI2S(p,b)             sendcmd(p,PARM,SI2S,WORD2(b),RET(0))#define EOB_STATUS         0x80000000	/* status flags : block boundary */#define EOS_STATUS         0x40000000	/*              : stoppped */#define EOC_STATUS         0x20000000	/*              : stream end */#define ERR_STATUS         0x10000000#define EMPTY_STATUS       0x08000000#define IEOB_ENABLE        0x1	/* enable interrupts for status notification above */#define IEOS_ENABLE        0x2#define IEOC_ENABLE        0x4#define RDONCE             0x8#define DESC_MAX_MASK      0xff#define ST_PLAY  0x1		/* stream states */#define ST_STOP  0x2#define ST_PAUSE 0x4#define I2S_INTDEC     3	/* config for I2S link */#define I2S_MERGER     0#define I2S_SPLITTER   0#define I2S_MIXER      7#define I2S_RATE       44100#define MODEM_INTDEC   4	/* config for modem link */#define MODEM_MERGER   3#define MODEM_SPLITTER 0#define MODEM_MIXER    11#define FM_INTDEC      3	/* config for FM/OPL3 link */#define FM_MERGER      0#define FM_SPLITTER    0#define FM_MIXER       9#define SPLIT_PATH  0x80	/* path splitting flag */enum FIRMWARE {	DATA_REC = 0, EXT_END_OF_FILE, EXT_SEG_ADDR_REC, EXT_GOTO_CMD_REC,	EXT_LIN_ADDR_REC,};enum CMDS {	GETV = 0x00, GETC, GUNS, SCID, RMEM =	    0x10, SMEM, WMEM, SDTM, GOTO, SSTR =	    0x20, PSTR, KSTR, KDMA, GPOS, SETF, GSTS, NGPOS, PSEL =	    0x30, PCLR, PLST, RSSV, LSEL, SSRC = 0x40, SLST, RSRC, SSRB, SDGV =	    0x50, RDGV, DLST, SACR = 0x60, RACR, ALST, TXAC, RXAC, SI2S =	    0x70, ARM_SETDPLL = 0x72,};enum E1SOURCE {	ARM2LBUS_FIFO0 = 0, ARM2LBUS_FIFO1, ARM2LBUS_FIFO2, ARM2LBUS_FIFO3,	ARM2LBUS_FIFO4, ARM2LBUS_FIFO5, ARM2LBUS_FIFO6, ARM2LBUS_FIFO7,	ARM2LBUS_FIFO8, ARM2LBUS_FIFO9, ARM2LBUS_FIFO10, ARM2LBUS_FIFO11,	ARM2LBUS_FIFO12, ARM2LBUS_FIFO13, ARM2LBUS_FIFO14, ARM2LBUS_FIFO15,	INTER0_OUT, INTER1_OUT, INTER2_OUT, INTER3_OUT, INTER4_OUT,	INTERM0_OUT, INTERM1_OUT, INTERM2_OUT, INTERM3_OUT, INTERM4_OUT,	INTERM5_OUT, INTERM6_OUT, DECIMM0_OUT, DECIMM1_OUT, DECIMM2_OUT,	DECIMM3_OUT, DECIM0_OUT, SR3_4_OUT, OPL3_SAMPLE, ASRC0, ASRC1,	ACLNK2PADC, ACLNK2MODEM0RX, ACLNK2MIC, ACLNK2MODEM1RX, ACLNK2HNDMIC,	DIGITAL_MIXER_OUT0, GAINFUNC0_OUT, GAINFUNC1_OUT, GAINFUNC2_OUT,	GAINFUNC3_OUT, GAINFUNC4_OUT, SOFTMODEMTX, SPLITTER0_OUTL,	SPLITTER0_OUTR, SPLITTER1_OUTL, SPLITTER1_OUTR, SPLITTER2_OUTL,	SPLITTER2_OUTR, SPLITTER3_OUTL, SPLITTER3_OUTR, MERGER0_OUT,	MERGER1_OUT, MERGER2_OUT, MERGER3_OUT, ARM2LBUS_FIFO_DIRECT, NO_OUT};enum E2SINK {	LBUS2ARM_FIFO0 = 0, LBUS2ARM_FIFO1, LBUS2ARM_FIFO2, LBUS2ARM_FIFO3,	LBUS2ARM_FIFO4, LBUS2ARM_FIFO5, LBUS2ARM_FIFO6, LBUS2ARM_FIFO7,	INTER0_IN, INTER1_IN, INTER2_IN, INTER3_IN, INTER4_IN, INTERM0_IN,	INTERM1_IN, INTERM2_IN, INTERM3_IN, INTERM4_IN, INTERM5_IN, INTERM6_IN,	DECIMM0_IN, DECIMM1_IN, DECIMM2_IN, DECIMM3_IN, DECIM0_IN, SR3_4_IN,	PDAC2ACLNK, MODEM0TX2ACLNK, MODEM1TX2ACLNK, HNDSPK2ACLNK,	DIGITAL_MIXER_IN0, DIGITAL_MIXER_IN1, DIGITAL_MIXER_IN2,	DIGITAL_MIXER_IN3, DIGITAL_MIXER_IN4, DIGITAL_MIXER_IN5,	DIGITAL_MIXER_IN6, DIGITAL_MIXER_IN7, DIGITAL_MIXER_IN8,	DIGITAL_MIXER_IN9, DIGITAL_MIXER_IN10, DIGITAL_MIXER_IN11,	GAINFUNC0_IN, GAINFUNC1_IN, GAINFUNC2_IN, GAINFUNC3_IN, GAINFUNC4_IN,	SOFTMODEMRX, SPLITTER0_IN, SPLITTER1_IN, SPLITTER2_IN, SPLITTER3_IN,	MERGER0_INL, MERGER0_INR, MERGER1_INL, MERGER1_INR, MERGER2_INL,	MERGER2_INR, MERGER3_INL, MERGER3_INR, E2SINK_MAX};enum LBUS_SINK {	LS_SRC_INTERPOLATOR = 0, LS_SRC_INTERPOLATORM, LS_SRC_DECIMATOR,	LS_SRC_DECIMATORM, LS_MIXER_IN, LS_MIXER_GAIN_FUNCTION,	LS_SRC_SPLITTER, LS_SRC_MERGER, LS_NONE1, LS_NONE2,};enum RT_CHANNEL_IDS {	M0TX = 0, M1TX, TAMTX, HSSPKR, PDAC, DSNDTX0, DSNDTX1, DSNDTX2,	DSNDTX3, DSNDTX4, DSNDTX5, DSNDTX6, DSNDTX7, WVSTRTX, COP3DTX, SPARE,	M0RX, HSMIC, M1RX, CLEANRX, MICADC, PADC, COPRX1, COPRX2,	CHANNEL_ID_COUNTER};enum { SB_CMD = 0, MODEM_CMD, I2S_CMD0, I2S_CMD1, FM_CMD, MAX_CMD };struct lbuspath {	unsigned char *noconv;	unsigned char *stereo;	unsigned char *mono;};struct cmdport {	u32 data1;		/* cmd,param */	u32 data2;		/* param */	u32 stat;		/* status */	u32 pad[5];};struct riptideport {	u32 audio_control;	/* status registers */	u32 audio_status;	u32 pad[2];	struct cmdport port[2];	/* command ports */};struct cmdif {	struct riptideport *hwport;	spinlock_t lock;	unsigned int cmdcnt;	/* cmd statistics */	unsigned int cmdtime;	unsigned int cmdtimemax;	unsigned int cmdtimemin;	unsigned int errcnt;	int is_reset;};struct riptide_firmware {	u16 ASIC;	u16 CODEC;	u16 AUXDSP;	u16 PROG;};union cmdret {	u8 retbytes[8];	u16 retwords[4];	u32 retlongs[2];};union firmware_version {	union cmdret ret;	struct riptide_firmware firmware;};#define get_pcmhwdev(substream) (struct pcmhw *)(substream->runtime->private_data)#define PLAYBACK_SUBSTREAMS 3struct snd_riptide {	struct snd_card *card;	struct pci_dev *pci;	const struct firmware *fw_entry;	struct cmdif *cif;	struct snd_pcm *pcm;	struct snd_pcm *pcm_i2s;	struct snd_rawmidi *rmidi;	struct snd_opl3 *opl3;	struct snd_ac97 *ac97;	struct snd_ac97_bus *ac97_bus;	struct snd_pcm_substream *playback_substream[PLAYBACK_SUBSTREAMS];	struct snd_pcm_substream *capture_substream;	int openstreams;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -