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

📄 cx88-alsa.c

📁 V4l driver for DVB HD
💻 C
📖 第 1 页 / 共 2 页
字号:
	cx88_risc_databuffer(chip->pci, &buf->risc,			buf->vb.dma.sglist,			buf->vb.width, buf->vb.height);	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);	buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma);	buf->vb.state = STATE_PREPARED;	buf->bpl = chip->period_size;	chip->buf = buf;	chip->dma_risc = buf->vb.dma;	dprintk(1,"Buffer ready at %u\n",chip->dma_risc.nr_pages);	substream->runtime->dma_area = chip->dma_risc.vmalloc;	return 0;}/* * hw free callback */#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,16)static int snd_cx88_hw_free(snd_pcm_substream_t * substream)#elsestatic int snd_cx88_hw_free(struct snd_pcm_substream * substream)#endif{	snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);	if (substream->runtime->dma_area) {		dsp_buffer_free(chip);		substream->runtime->dma_area = NULL;	}	return 0;}/* * prepare callback */#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,16)static int snd_cx88_prepare(snd_pcm_substream_t *substream)#elsestatic int snd_cx88_prepare(struct snd_pcm_substream *substream)#endif{	return 0;}/* * trigger callback */#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,16)static int snd_cx88_card_trigger(snd_pcm_substream_t *substream, int cmd)#elsestatic int snd_cx88_card_trigger(struct snd_pcm_substream *substream, int cmd)#endif{	snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);	int err;	spin_lock(&chip->reg_lock);	switch (cmd) {	case SNDRV_PCM_TRIGGER_START:		err=_cx88_start_audio_dma(chip);		break;	case SNDRV_PCM_TRIGGER_STOP:		err=_cx88_stop_audio_dma(chip);		break;	default:		err=-EINVAL;		break;	}	spin_unlock(&chip->reg_lock);	return err;}/* * pointer callback */#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,16)static snd_pcm_uframes_t snd_cx88_pointer(snd_pcm_substream_t *substream)#elsestatic snd_pcm_uframes_t snd_cx88_pointer(struct snd_pcm_substream *substream)#endif{	snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,16)	snd_pcm_runtime_t *runtime = substream->runtime;#else	struct snd_pcm_runtime *runtime = substream->runtime;#endif	if (chip->read_count) {		chip->read_count -= snd_pcm_lib_period_bytes(substream);		chip->read_offset += snd_pcm_lib_period_bytes(substream);		if (chip->read_offset == chip->dma_size)			chip->read_offset = 0;	}	dprintk(2, "Pointer time, will return %li, read %li\n",chip->read_offset,chip->read_count);	return bytes_to_frames(runtime, chip->read_offset);}/* * operators */#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,16)static snd_pcm_ops_t snd_cx88_pcm_ops = {#elsestatic struct snd_pcm_ops snd_cx88_pcm_ops = {#endif	.open = snd_cx88_pcm_open,	.close = snd_cx88_close,	.ioctl = snd_pcm_lib_ioctl,	.hw_params = snd_cx88_hw_params,	.hw_free = snd_cx88_hw_free,	.prepare = snd_cx88_prepare,	.trigger = snd_cx88_card_trigger,	.pointer = snd_cx88_pointer,};/* * create a PCM device */static int __devinit snd_cx88_pcm(snd_cx88_card_t *chip, int device, char *name){	int err;#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,16)	snd_pcm_t *pcm;#else	struct snd_pcm *pcm;#endif	err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm);	if (err < 0)		return err;	pcm->private_data = chip;	strcpy(pcm->name, name);	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cx88_pcm_ops);	return 0;}/****************************************************************************				CONTROL INTERFACE ****************************************************************************/#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,16)static int snd_cx88_capture_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *info)#elsestatic int snd_cx88_capture_volume_info(struct snd_kcontrol *kcontrol,					struct snd_ctl_elem_info *info)#endif{	info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;	info->count = 1;	info->value.integer.min = 0;	info->value.integer.max = 0x3f;	return 0;}/* OK - TODO: test it */#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,16)static int snd_cx88_capture_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)#elsestatic int snd_cx88_capture_volume_get(struct snd_kcontrol *kcontrol,				       struct snd_ctl_elem_value *value)#endif{	snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);	struct cx88_core *core=chip->core;	value->value.integer.value[0] = 0x3f - (cx_read(AUD_VOL_CTL) & 0x3f);	return 0;}/* OK - TODO: test it */#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,16)static int snd_cx88_capture_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)#elsestatic int snd_cx88_capture_volume_put(struct snd_kcontrol *kcontrol,				       struct snd_ctl_elem_value *value)#endif{	snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);	struct cx88_core *core=chip->core;	int v;	u32 old_control;	spin_lock_irq(&chip->reg_lock);	old_control = 0x3f - (cx_read(AUD_VOL_CTL) & 0x3f);	v = 0x3f - (value->value.integer.value[0] & 0x3f);	cx_andor(AUD_VOL_CTL, 0x3f, v);	spin_unlock_irq(&chip->reg_lock);	return v != old_control;}#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,16)static snd_kcontrol_new_t snd_cx88_capture_volume = {#elsestatic struct snd_kcontrol_new snd_cx88_capture_volume = {#endif	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	.name = "Capture Volume",	.info = snd_cx88_capture_volume_info,	.get = snd_cx88_capture_volume_get,	.put = snd_cx88_capture_volume_put,};/****************************************************************************			Basic Flow for Sound Devices ****************************************************************************//* * PCI ID Table - 14f1:8801 and 14f1:8811 means function 1: Audio * Only boards with eeprom and byte 1 at eeprom=1 have it */static struct pci_device_id cx88_audio_pci_tbl[] = {	{0x14f1,0x8801,PCI_ANY_ID,PCI_ANY_ID,0,0,0},	{0x14f1,0x8811,PCI_ANY_ID,PCI_ANY_ID,0,0,0},	{0, }};MODULE_DEVICE_TABLE(pci, cx88_audio_pci_tbl);/* * Chip-specific destructor */static int snd_cx88_free(snd_cx88_card_t *chip){	if (chip->irq >= 0){		synchronize_irq(chip->irq);		free_irq(chip->irq, chip);	}	cx88_core_put(chip->core,chip->pci);	pci_disable_device(chip->pci);	return 0;}/* * Component Destructor */#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,16)static void snd_cx88_dev_free(snd_card_t * card)#elsestatic void snd_cx88_dev_free(struct snd_card * card)#endif{	snd_cx88_card_t *chip = card->private_data;	snd_cx88_free(chip);}/* * Alsa Constructor - Component probe */static int devno;#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,16)static int __devinit snd_cx88_create(snd_card_t *card, struct pci_dev *pci,				    snd_cx88_card_t **rchip)#elsestatic int __devinit snd_cx88_create(struct snd_card *card,				     struct pci_dev *pci,				     snd_cx88_card_t **rchip)#endif{	snd_cx88_card_t   *chip;	struct cx88_core  *core;	int               err;	*rchip = NULL;	err = pci_enable_device(pci);	if (err < 0)		return err;	pci_set_master(pci);	chip = (snd_cx88_card_t *) card->private_data;	core = cx88_core_get(pci);	if (NULL == core) {		err = -EINVAL;		kfree (chip);		return err;	}	if (!pci_dma_supported(pci,0xffffffff)) {		dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n",core->name);		err = -EIO;		cx88_core_put(core,pci);		return err;	}	/* pci init */	chip->card = card;	chip->pci = pci;	chip->irq = -1;	spin_lock_init(&chip->reg_lock);	cx88_reset(core);	chip->core = core;	/* get irq */	err = request_irq(chip->pci->irq, cx8801_irq,			  SA_SHIRQ | SA_INTERRUPT, chip->core->name, chip);	if (err < 0) {		dprintk(0, "%s: can't get IRQ %d\n",		       chip->core->name, chip->pci->irq);		return err;	}	/* print pci info */	pci_read_config_byte(pci, PCI_CLASS_REVISION, &chip->pci_rev);	pci_read_config_byte(pci, PCI_LATENCY_TIMER,  &chip->pci_lat);	dprintk(1,"ALSA %s/%i: found at %s, rev: %d, irq: %d, "	       "latency: %d, mmio: 0x%lx\n", core->name, devno,	       pci_name(pci), chip->pci_rev, pci->irq,	       chip->pci_lat,pci_resource_start(pci,0));	chip->irq = pci->irq;	synchronize_irq(chip->irq);	snd_card_set_dev(card, &pci->dev);	*rchip = chip;	return 0;}static int __devinit cx88_audio_initdev(struct pci_dev *pci,				    const struct pci_device_id *pci_id){#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,16)	snd_card_t       *card;#else	struct snd_card  *card;#endif	snd_cx88_card_t  *chip;	int              err;	if (devno >= SNDRV_CARDS)		return (-ENODEV);	if (!enable[devno]) {		++devno;		return (-ENOENT);	}	card = snd_card_new(index[devno], id[devno], THIS_MODULE, sizeof(snd_cx88_card_t));	if (!card)		return (-ENOMEM);	card->private_free = snd_cx88_dev_free;	err = snd_cx88_create(card, pci, &chip);	if (err < 0)		return (err);	err = snd_cx88_pcm(chip, 0, "CX88 Digital");	if (err < 0) {		snd_card_free(card);		return (err);	}	err = snd_ctl_add(card, snd_ctl_new1(&snd_cx88_capture_volume, chip));	if (err < 0) {		snd_card_free(card);		return (err);	}	strcpy (card->driver, "CX88x");	sprintf(card->shortname, "Conexant CX%x", pci->device);	sprintf(card->longname, "%s at %#lx",		card->shortname, pci_resource_start(pci, 0));	strcpy (card->mixername, "CX88");	dprintk (0, "%s/%i: ALSA support for cx2388x boards\n",	       card->driver,devno);	err = snd_card_register(card);	if (err < 0) {		snd_card_free(card);		return (err);	}	snd_cx88_cards[devno] = card;	pci_set_drvdata(pci,card);	devno++;	return 0;}/* * ALSA destructor */static void __devexit cx88_audio_finidev(struct pci_dev *pci){	struct cx88_audio_dev *card = pci_get_drvdata(pci);	snd_card_free((void *)card);	pci_set_drvdata(pci, NULL);	devno--;}#if 0	.suspend  = cx88_audio_suspend,	.resume   = cx88_audio_resume,#endif/* * PCI driver definition */static struct pci_driver cx88_audio_pci_driver = {	.name     = "cx88_audio",	.id_table = cx88_audio_pci_tbl,	.probe    = cx88_audio_initdev,	.remove   = cx88_audio_finidev,};/****************************************************************************				LINUX MODULE INIT ****************************************************************************//* * module init */static int cx88_audio_init(void){	printk(KERN_INFO "cx2388x alsa driver version %d.%d.%d loaded\n",	       (CX88_VERSION_CODE >> 16) & 0xff,	       (CX88_VERSION_CODE >>  8) & 0xff,	       CX88_VERSION_CODE & 0xff);#ifdef SNAPSHOT	printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",	       SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);#endif	return pci_register_driver(&cx88_audio_pci_driver);}/* * module remove */static void cx88_audio_fini(void){	pci_unregister_driver(&cx88_audio_pci_driver);}module_init(cx88_audio_init);module_exit(cx88_audio_fini);/* ----------------------------------------------------------- *//* * Local variables: * c-basic-offset: 8 * End: */

⌨️ 快捷键说明

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