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

📄 riptide.c

📁 LINUX 2.6.17.4的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	int irq;	unsigned long port;	unsigned short mpuaddr;	unsigned short opladdr;#ifdef SUPPORT_JOYSTICK	unsigned short gameaddr;#endif	struct resource *res_port;	unsigned short device_id;	union firmware_version firmware;	spinlock_t lock;	struct tasklet_struct riptide_tq;	struct snd_info_entry *proc_entry;	unsigned long received_irqs;	unsigned long handled_irqs;#ifdef CONFIG_PM	int in_suspend;#endif};struct sgd {			/* scatter gather desriptor */	u32 dwNextLink;	u32 dwSegPtrPhys;	u32 dwSegLen;	u32 dwStat_Ctl;};struct pcmhw {			/* pcm descriptor */	struct lbuspath paths;	unsigned char *lbuspath;	unsigned char source;	unsigned char intdec[2];	unsigned char mixer;	unsigned char id;	unsigned char state;	unsigned int rate;	unsigned int channels;	snd_pcm_format_t format;	struct snd_dma_buffer sgdlist;	struct sgd *sgdbuf;	unsigned int size;	unsigned int pages;	unsigned int oldpos;	unsigned int pointer;};#define CMDRET_ZERO (union cmdret){{(u32)0, (u32) 0}}static int sendcmd(struct cmdif *cif, u32 flags, u32 cmd, u32 parm,		   union cmdret *ret);static int getsourcesink(struct cmdif *cif, unsigned char source,			 unsigned char sink, unsigned char *a,			 unsigned char *b);static int snd_riptide_initialize(struct snd_riptide *chip);static int riptide_reset(struct cmdif *cif, struct snd_riptide *chip);/* */static struct pci_device_id snd_riptide_ids[] __devinitdata = {	{	 .vendor = 0x127a,.device = 0x4310,	 .subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID,	 },	{	 .vendor = 0x127a,.device = 0x4320,	 .subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID,	 },	{	 .vendor = 0x127a,.device = 0x4330,	 .subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID,	 },	{	 .vendor = 0x127a,.device = 0x4340,	 .subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID,	 },	{0,},};#ifdef SUPPORT_JOYSTICKstatic struct pci_device_id snd_riptide_joystick_ids[] __devinitdata = {	{	 .vendor = 0x127a,.device = 0x4312,	 .subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID,	 },	{	 .vendor = 0x127a,.device = 0x4322,	 .subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID,	 },	{.vendor = 0x127a,.device = 0x4332,	 .subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID,	 },	{.vendor = 0x127a,.device = 0x4342,	 .subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID,	 },	{0,},};#endifMODULE_DEVICE_TABLE(pci, snd_riptide_ids);/* */static unsigned char lbusin2out[E2SINK_MAX + 1][2] = {	{NO_OUT, LS_NONE1}, {NO_OUT, LS_NONE2}, {NO_OUT, LS_NONE1}, {NO_OUT,								     LS_NONE2},	{NO_OUT, LS_NONE1}, {NO_OUT, LS_NONE2}, {NO_OUT, LS_NONE1}, {NO_OUT,								     LS_NONE2},	{INTER0_OUT, LS_SRC_INTERPOLATOR}, {INTER1_OUT, LS_SRC_INTERPOLATOR},	{INTER2_OUT, LS_SRC_INTERPOLATOR}, {INTER3_OUT, LS_SRC_INTERPOLATOR},	{INTER4_OUT, LS_SRC_INTERPOLATOR}, {INTERM0_OUT, LS_SRC_INTERPOLATORM},	{INTERM1_OUT, LS_SRC_INTERPOLATORM}, {INTERM2_OUT,					      LS_SRC_INTERPOLATORM},	{INTERM3_OUT, LS_SRC_INTERPOLATORM}, {INTERM4_OUT,					      LS_SRC_INTERPOLATORM},	{INTERM5_OUT, LS_SRC_INTERPOLATORM}, {INTERM6_OUT,					      LS_SRC_INTERPOLATORM},	{DECIMM0_OUT, LS_SRC_DECIMATORM}, {DECIMM1_OUT, LS_SRC_DECIMATORM},	{DECIMM2_OUT, LS_SRC_DECIMATORM}, {DECIMM3_OUT, LS_SRC_DECIMATORM},	{DECIM0_OUT, LS_SRC_DECIMATOR}, {SR3_4_OUT, LS_NONE1}, {NO_OUT,								LS_NONE2},	{NO_OUT, LS_NONE1}, {NO_OUT, LS_NONE2}, {NO_OUT, LS_NONE1},	{DIGITAL_MIXER_OUT0, LS_MIXER_IN}, {DIGITAL_MIXER_OUT0, LS_MIXER_IN},	{DIGITAL_MIXER_OUT0, LS_MIXER_IN}, {DIGITAL_MIXER_OUT0, LS_MIXER_IN},	{DIGITAL_MIXER_OUT0, LS_MIXER_IN}, {DIGITAL_MIXER_OUT0, LS_MIXER_IN},	{DIGITAL_MIXER_OUT0, LS_MIXER_IN}, {DIGITAL_MIXER_OUT0, LS_MIXER_IN},	{DIGITAL_MIXER_OUT0, LS_MIXER_IN}, {DIGITAL_MIXER_OUT0, LS_MIXER_IN},	{DIGITAL_MIXER_OUT0, LS_MIXER_IN}, {DIGITAL_MIXER_OUT0, LS_MIXER_IN},	{GAINFUNC0_OUT, LS_MIXER_GAIN_FUNCTION}, {GAINFUNC1_OUT,						  LS_MIXER_GAIN_FUNCTION},	{GAINFUNC2_OUT, LS_MIXER_GAIN_FUNCTION}, {GAINFUNC3_OUT,						  LS_MIXER_GAIN_FUNCTION},	{GAINFUNC4_OUT, LS_MIXER_GAIN_FUNCTION}, {SOFTMODEMTX, LS_NONE1},	{SPLITTER0_OUTL, LS_SRC_SPLITTER}, {SPLITTER1_OUTL, LS_SRC_SPLITTER},	{SPLITTER2_OUTL, LS_SRC_SPLITTER}, {SPLITTER3_OUTL, LS_SRC_SPLITTER},	{MERGER0_OUT, LS_SRC_MERGER}, {MERGER0_OUT, LS_SRC_MERGER},	{MERGER1_OUT, LS_SRC_MERGER},	{MERGER1_OUT, LS_SRC_MERGER}, {MERGER2_OUT, LS_SRC_MERGER},	{MERGER2_OUT, LS_SRC_MERGER},	{MERGER3_OUT, LS_SRC_MERGER}, {MERGER3_OUT, LS_SRC_MERGER}, {NO_OUT,								     LS_NONE2},};static unsigned char lbus_play_opl3[] = {	DIGITAL_MIXER_IN0 + FM_MIXER, 0xff};static unsigned char lbus_play_modem[] = {	DIGITAL_MIXER_IN0 + MODEM_MIXER, 0xff};static unsigned char lbus_play_i2s[] = {	INTER0_IN + I2S_INTDEC, DIGITAL_MIXER_IN0 + I2S_MIXER, 0xff};static unsigned char lbus_play_out[] = {	PDAC2ACLNK, 0xff};static unsigned char lbus_play_outhp[] = {	HNDSPK2ACLNK, 0xff};static unsigned char lbus_play_noconv1[] = {	DIGITAL_MIXER_IN0, 0xff};static unsigned char lbus_play_stereo1[] = {	INTER0_IN, DIGITAL_MIXER_IN0, 0xff};static unsigned char lbus_play_mono1[] = {	INTERM0_IN, DIGITAL_MIXER_IN0, 0xff};static unsigned char lbus_play_noconv2[] = {	DIGITAL_MIXER_IN1, 0xff};static unsigned char lbus_play_stereo2[] = {	INTER1_IN, DIGITAL_MIXER_IN1, 0xff};static unsigned char lbus_play_mono2[] = {	INTERM1_IN, DIGITAL_MIXER_IN1, 0xff};static unsigned char lbus_play_noconv3[] = {	DIGITAL_MIXER_IN2, 0xff};static unsigned char lbus_play_stereo3[] = {	INTER2_IN, DIGITAL_MIXER_IN2, 0xff};static unsigned char lbus_play_mono3[] = {	INTERM2_IN, DIGITAL_MIXER_IN2, 0xff};static unsigned char lbus_rec_noconv1[] = {	LBUS2ARM_FIFO5, 0xff};static unsigned char lbus_rec_stereo1[] = {	DECIM0_IN, LBUS2ARM_FIFO5, 0xff};static unsigned char lbus_rec_mono1[] = {	DECIMM3_IN, LBUS2ARM_FIFO5, 0xff};static unsigned char play_ids[] = { 4, 1, 2, };static unsigned char play_sources[] = {	ARM2LBUS_FIFO4, ARM2LBUS_FIFO1, ARM2LBUS_FIFO2,};static struct lbuspath lbus_play_paths[] = {	{	 .noconv = lbus_play_noconv1,	 .stereo = lbus_play_stereo1,	 .mono = lbus_play_mono1,	 },	{	 .noconv = lbus_play_noconv2,	 .stereo = lbus_play_stereo2,	 .mono = lbus_play_mono2,	 },	{	 .noconv = lbus_play_noconv3,	 .stereo = lbus_play_stereo3,	 .mono = lbus_play_mono3,	 },};static struct lbuspath lbus_rec_path = {	.noconv = lbus_rec_noconv1,	.stereo = lbus_rec_stereo1,	.mono = lbus_rec_mono1,};#define FIRMWARE_VERSIONS 1static union firmware_version firmware_versions[] = {	{	 .firmware.ASIC = 3,.firmware.CODEC = 2,	 .firmware.AUXDSP = 3,.firmware.PROG = 773,	 },};static u32 atoh(unsigned char *in, unsigned int len){	u32 sum = 0;	unsigned int mult = 1;	unsigned char c;	while (len) {		c = in[len - 1];		if ((c >= '0') && (c <= '9'))			sum += mult * (c - '0');		else if ((c >= 'A') && (c <= 'F'))			sum += mult * (c - ('A' - 10));		else if ((c >= 'a') && (c <= 'f'))			sum += mult * (c - ('a' - 10));		mult *= 16;		--len;	}	return sum;}static int senddata(struct cmdif *cif, unsigned char *in, u32 offset){	u32 addr;	u32 data;	u32 i;	unsigned char *p;	i = atoh(&in[1], 2);	addr = offset + atoh(&in[3], 4);	if (SEND_SMEM(cif, 0, addr) != 0)		return -EACCES;	p = in + 9;	while (i) {		data = atoh(p, 8);		if (SEND_WMEM(cif, 2,			      ((data & 0x0f0f0f0f) << 4) | ((data & 0xf0f0f0f0)							    >> 4)))			return -EACCES;		i -= 4;		p += 8;	}	return 0;}static int loadfirmware(struct cmdif *cif, unsigned char *img,			unsigned int size){	unsigned char *in;	u32 laddr, saddr, t, val;	int err = 0;	laddr = saddr = 0;	while (size > 0 && err == 0) {		in = img;		if (in[0] == ':') {			t = atoh(&in[7], 2);			switch (t) {			case DATA_REC:				err = senddata(cif, in, laddr + saddr);				break;			case EXT_SEG_ADDR_REC:				saddr = atoh(&in[9], 4) << 4;				break;			case EXT_LIN_ADDR_REC:				laddr = atoh(&in[9], 4) << 16;				break;			case EXT_GOTO_CMD_REC:				val = atoh(&in[9], 8);				if (SEND_GOTO(cif, val) != 0)					err = -EACCES;				break;			case EXT_END_OF_FILE:				size = 0;				break;			default:				break;			}			while (size > 0) {				size--;				if (*img++ == '\n')					break;			}		}	}	snd_printdd("load firmware return %d\n", err);	return err;}static voidalloclbuspath(struct cmdif *cif, unsigned char source,	      unsigned char *path, unsigned char *mixer, unsigned char *s){	while (*path != 0xff) {		unsigned char sink, type;		sink = *path & (~SPLIT_PATH);		if (sink != E2SINK_MAX) {			snd_printdd("alloc path 0x%x->0x%x\n", source, sink);			SEND_PSEL(cif, source, sink);			source = lbusin2out[sink][0];			type = lbusin2out[sink][1];			if (type == LS_MIXER_IN) {				if (mixer)					*mixer = sink - DIGITAL_MIXER_IN0;			}			if (type == LS_SRC_DECIMATORM ||			    type == LS_SRC_DECIMATOR ||			    type == LS_SRC_INTERPOLATORM ||			    type == LS_SRC_INTERPOLATOR) {				if (s) {					if (s[0] != 0xff)						s[1] = sink;					else						s[0] = sink;				}			}		}		if (*path++ & SPLIT_PATH) {			unsigned char *npath = path;			while (*npath != 0xff)				npath++;			alloclbuspath(cif, source + 1, ++npath, mixer, s);		}	}}static voidfreelbuspath(struct cmdif *cif, unsigned char source, unsigned char *path){	while (*path != 0xff) {		unsigned char sink;		sink = *path & (~SPLIT_PATH);		if (sink != E2SINK_MAX) {			snd_printdd("free path 0x%x->0x%x\n", source, sink);			SEND_PCLR(cif, source, sink);			source = lbusin2out[sink][0];		}		if (*path++ & SPLIT_PATH) {			unsigned char *npath = path;			while (*npath != 0xff)				npath++;			freelbuspath(cif, source + 1, ++npath);		}	}}static int writearm(struct cmdif *cif, u32 addr, u32 data, u32 mask){	union cmdret rptr = CMDRET_ZERO;	unsigned int i = MAX_WRITE_RETRY;	int flag = 1;	SEND_RMEM(cif, 0x02, addr, &rptr);	rptr.retlongs[0] &= (~mask);	while (--i) {		SEND_SMEM(cif, 0x01, addr);		SEND_WMEM(cif, 0x02, (rptr.retlongs[0] | data));		SEND_RMEM(cif, 0x02, addr, &rptr);		if ((rptr.retlongs[0] & data) == data) {			flag = 0;			break;		} else			rptr.retlongs[0] &= ~mask;	}	snd_printdd("send arm 0x%x 0x%x 0x%x return %d\n", addr, data, mask,		    flag);	return flag;}static int sendcmd(struct cmdif *cif, u32 flags, u32 cmd, u32 parm,		   union cmdret *ret){	int i, j;	int err;	unsigned int time = 0;	unsigned long irqflags;	struct riptideport *hwport;	struct cmdport *cmdport = NULL;	snd_assert(cif, return -EINVAL);	hwport = cif->hwport;	if (cif->errcnt > MAX_ERROR_COUNT) {		if (cif->is_reset) {			snd_printk(KERN_ERR				   "Riptide: Too many failed cmds, reinitializing\n");			if (riptide_reset(cif, NULL) == 0) {				cif->errcnt = 0;				return -EIO;			}		}		snd_printk(KERN_ERR "Riptide: Initialization failed.\n");		return -EINVAL;	}	if (ret) {		ret->retlongs[0] = 0;		ret->retlongs[1] = 0;	}	i = 0;	spin_lock_irqsave(&cif->lock, irqflags);	while (i++ < CMDIF_TIMEOUT && !IS_READY(cif->hwport))		udelay(10);	if (i >= CMDIF_TIMEOUT) {		err = -EBUSY;

⌨️ 快捷键说明

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