示例#1
0
/*
 * usbctl_init()
 * Module load time. Allocate dma and interrupt resources. Setup /proc fs
 * entry. Leave UDC disabled.
 */
int usbctl_init( void )
{
	int retval = 0;
	
	// Disable UDC
	UDC_set( Ser0UDCCR, UDCCR_UDD);

	memset( &usbd_info, 0, sizeof( usbd_info ) );

	if (!port_changed_buf) {
		port_changed_buf = kmalloc(1, GFP_ATOMIC);
	}

	if (!desc_buf) {
		desc_buf = kmalloc(USB_BUFSIZ, GFP_ATOMIC);
	}

	/* setup rx dma */
	retval = sa1100_request_dma(DMA_Ser0UDCRd, "USB receive", NULL, NULL, &usbd_info.dmach_rx);
	if (retval) {
		printk("[%lu]%sunable to register for rx dma rc=%d\n", (jiffies-start_time)*10, pszctl, retval );
		goto err_rx_dma;
	}

	/* setup tx dma */
	retval = sa1100_request_dma(DMA_Ser0UDCWr, "USB transmit", NULL, NULL, &usbd_info.dmach_tx);
	if (retval) {
		printk("[%lu]%sunable to register for tx dma rc=%d\n", (jiffies-start_time)*10,pszctl,retval);
		goto err_tx_dma;
	}

	/* now allocate the IRQ. */
	retval = request_irq(IRQ_Ser0UDC, udc_int_hndlr, SA_INTERRUPT, "SA USB core", NULL);
	if (retval) {
		printk("[%lu]%sCouldn't request USB irq rc=%d\n", (jiffies-start_time)*10,pszctl, retval);
		goto err_irq;
	}

	return 0;

err_irq:
	sa1100_free_dma(usbd_info.dmach_tx);
	usbd_info.dmach_tx = 0;

err_tx_dma:
	sa1100_free_dma(usbd_info.dmach_rx);
	usbd_info.dmach_rx = 0;
err_rx_dma:
	return retval;
}
示例#2
0
static int sa1100_irda_start(struct net_device *dev)
{
	struct sa1100_irda *si = dev->priv;
	int err;

	si->speed = 9600;

	err = request_irq(dev->irq, sa1100_irda_irq, 0, dev->name, dev);
	if (err)
		goto err_irq;

	err = sa1100_request_dma(DMA_Ser2HSSPRd, "IrDA receive",
				 NULL, NULL, &si->rxdma);
	if (err)
		goto err_rx_dma;

	err = sa1100_request_dma(DMA_Ser2HSSPWr, "IrDA transmit",
				 sa1100_irda_txdma_irq, dev, &si->txdma);
	if (err)
		goto err_tx_dma;

	/*
	 * The interrupt must remain disabled for now.
	 */
	disable_irq(dev->irq);

	/*
	 * Setup the serial port for the specified speed.
	 */
	err = sa1100_irda_startup(si);
	if (err)
		goto err_startup;

	/*
	 * Open a new IrLAP layer instance.
	 */
	si->irlap = irlap_open(dev, &si->qos, "sa1100");
	err = -ENOMEM;
	if (!si->irlap)
		goto err_irlap;

	/*
	 * Now enable the interrupt and start the queue
	 */
	si->open = 1;
	sa1100_set_power(si, power_level); /* low power mode */
	enable_irq(dev->irq);
	netif_start_queue(dev);
	return 0;

err_irlap:
	si->open = 0;
	sa1100_irda_shutdown(si);
err_startup:
	sa1100_free_dma(si->txdma);
err_tx_dma:
	sa1100_free_dma(si->rxdma);
err_rx_dma:
	free_irq(dev->irq, dev);
err_irq:
	return err;
}
示例#3
0
int sa1100_audio_attach(struct inode *inode, struct file *file,
			  audio_state_t *state)
{
	int err, need_tx_dma;

	DPRINTK("audio_open\n");

	down(&state->sem);

	/* access control */
	err = -ENODEV;
	if ((file->f_mode & FMODE_WRITE) && !state->output_stream)
		goto out;
	if ((file->f_mode & FMODE_READ) && !state->input_stream)
		goto out;
	err = -EBUSY;
	if ((file->f_mode & FMODE_WRITE) && state->wr_ref)
		goto out;
	if ((file->f_mode & FMODE_READ) && state->rd_ref)
		goto out;
	err = -EINVAL;
	if ((file->f_mode & FMODE_READ) && state->need_tx_for_rx && !state->output_stream)
		goto out;

	/* request DMA channels */
	if (state->skip_dma_init)
		goto skip_dma;
	need_tx_dma = ((file->f_mode & FMODE_WRITE) ||
		       ((file->f_mode & FMODE_READ) && state->need_tx_for_rx));
	if (state->wr_ref || (state->rd_ref && state->need_tx_for_rx))
		need_tx_dma = 0;
	if (need_tx_dma) {
		err = sa1100_request_dma(&state->output_stream->dma_ch,
					 state->output_id,
					 state->output_dma);
		if (err)
			goto out;
	}
	if (file->f_mode & FMODE_READ) {
		err = sa1100_request_dma(&state->input_stream->dma_ch,
					 state->input_id,
					 state->input_dma);
		if (err) {
			if (need_tx_dma)
				sa1100_free_dma(state->output_stream->dma_ch);
			goto out;
		}
	}
skip_dma:

	/* now complete initialisation */
	if (!AUDIO_ACTIVE(state)) {
		if (state->hw_init)
			state->hw_init(state->data);
#ifdef CONFIG_PM
		state->pm_dev = pm_register(PM_SYS_DEV, 0, audio_pm_callback);
		if (state->pm_dev)
			state->pm_dev->data = state;
#endif
	}

	if ((file->f_mode & FMODE_WRITE)) {
		state->wr_ref = 1;
		audio_clear_buf(state->output_stream);
		state->output_stream->fragsize = AUDIO_FRAGSIZE_DEFAULT;
		state->output_stream->nbfrags = AUDIO_NBFRAGS_DEFAULT;
		state->output_stream->mapped = 0;
		sa1100_dma_set_callback(state->output_stream->dma_ch,
					audio_dmaout_done_callback);
		init_waitqueue_head(&state->output_stream->wq);
	}
	if (file->f_mode & FMODE_READ) {
		state->rd_ref = 1;
		audio_clear_buf(state->input_stream);
		state->input_stream->fragsize = AUDIO_FRAGSIZE_DEFAULT;
		state->input_stream->nbfrags = AUDIO_NBFRAGS_DEFAULT;
		state->input_stream->mapped = 0;
		sa1100_dma_set_callback(state->input_stream->dma_ch,
					audio_dmain_done_callback);
		init_waitqueue_head(&state->input_stream->wq);
	}

	file->private_data	= state;
	file->f_op->release	= audio_release;
	file->f_op->write	= audio_write;
	file->f_op->read	= audio_read;
	file->f_op->mmap	= audio_mmap;
	file->f_op->poll	= audio_poll;
	file->f_op->ioctl	= audio_ioctl;
	file->f_op->llseek	= audio_llseek;
	err = 0;

out:
	up(&state->sem);
	return err;
}