Example #1
0
static snd_pcm_uframes_t cygnus_pcm_pointer(struct snd_pcm_substream *substream)
{
	struct cygnus_aio_port *aio;
	unsigned int res = 0, cur = 0, base = 0;
	struct ringbuf_regs *p_rbuf = NULL;

	aio = cygnus_dai_get_dma_data(substream);

	/*
	 * Get the offset of the current read (for playack) or write
	 * index (for capture).  Report this value back to the asoc framework.
	 */
	p_rbuf = get_ringbuf(substream);
	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		cur = readl(aio->cygaud->audio + p_rbuf->rdaddr);
	else
		cur = readl(aio->cygaud->audio + p_rbuf->wraddr);

	base = readl(aio->cygaud->audio + p_rbuf->baseaddr);

	/*
	 * Mask off the MSB of the rdaddr,wraddr and baseaddr
	 * since MSB is not part of the address
	 */
	res = (cur & 0x7fffffff) - (base & 0x7fffffff);

	return bytes_to_frames(substream->runtime, res);
}
Example #2
0
static void cygnus_pcm_period_elapsed(struct snd_pcm_substream *substream)
{
	struct cygnus_aio_port *aio;
	struct ringbuf_regs *p_rbuf = NULL;
	u32 regval;

	aio = cygnus_dai_get_dma_data(substream);

	p_rbuf = get_ringbuf(substream);

	/*
	 * If free/full mark interrupt occurs, provide timestamp
	 * to ALSA and update appropriate idx by period_bytes
	 */
	snd_pcm_period_elapsed(substream);

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		/* Set the ring buffer to full */
		regval = readl(aio->cygaud->audio + p_rbuf->rdaddr);
		regval = regval ^ BIT(31);
		writel(regval, aio->cygaud->audio + p_rbuf->wraddr);
	} else {
		/* Set the ring buffer to empty */
		regval = readl(aio->cygaud->audio + p_rbuf->wraddr);
		writel(regval, aio->cygaud->audio + p_rbuf->rdaddr);
	}
}
Example #3
0
static int cygnus_pcm_prepare(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct cygnus_aio_port *aio;
	unsigned long bufsize, periodsize;
	int ret = 0;
	bool is_play;
	u32 start;
	struct ringbuf_regs *p_rbuf = NULL;

	aio = cygnus_dai_get_dma_data(substream);
	dev_dbg(rtd->cpu_dai->dev, "%s port %d\n", __func__, aio->portnum);

	bufsize = snd_pcm_lib_buffer_bytes(substream);
	periodsize = snd_pcm_lib_period_bytes(substream);

	dev_dbg(rtd->cpu_dai->dev, "%s (buf_size %lu) (period_size %lu)\n",
			__func__, bufsize, periodsize);

	configure_ringbuf_regs(substream);

	p_rbuf = get_ringbuf(substream);

	start = runtime->dma_addr;

	is_play = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 1 : 0;

	ringbuf_set_initial(aio->cygaud->audio, p_rbuf, is_play, start,
				periodsize, bufsize);

	return ret;
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(rx_data_process, ev, data)
{
  PROCESS_BEGIN();
  
  /* Process is polled whenever data is available from uart isr */
  uint8_t c;

  while(1) {
    PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
    /* Read RX ringbuffer. ASCII chars Output when LF is seen. 
       If overflowed, strings are skipped */ 
    do {
      if (get_ringbuf(&c) == -1) {
        break;    /* No more rx char's in ringbuffer */
      } else {
        if (rx_buf_index == RX_BUFFER_SIZE) {   /* Skip current content if buffer full */
          rx_buf_index = 0;
        } 
        rx_buf[rx_buf_index++] = c;
        if ((c == '\n')||(c == '\r')) {
          rx_buf[rx_buf_index] = '\0';
          printf("RX on UART1: %s", rx_buf);   
          /* Signal event to coap clients.
             Demo assumes data is consumed before new data comes in */
          event_coap_rx_uart1_handler();     
          rx_buf_index = 0;      
        }
      }
    } while (1);
  }
  PROCESS_END();
}
Example #5
0
/* get data from ring buffer and then write to usb bus */
static void spcp8x5_send(struct usb_serial_port *port)
{
	int count, result;
	struct spcp8x5_private *priv = usb_get_serial_port_data(port);
	unsigned long flags;

	spin_lock_irqsave(&priv->lock, flags);

	if (priv->write_urb_in_use) {
		dev_dbg(&port->dev, "write urb still used\n");
		spin_unlock_irqrestore(&priv->lock, flags);
		return;
	}

	/* send the 1st urb for writting */
	memset(port->write_urb->transfer_buffer , 0x00 , port->bulk_out_size);
	count = get_ringbuf(priv->buf, port->write_urb->transfer_buffer,
		port->bulk_out_size);

	if (count == 0) {
		spin_unlock_irqrestore(&priv->lock, flags);
		return;
	}

	/* update the urb status */
	priv->write_urb_in_use = 1;

	spin_unlock_irqrestore(&priv->lock, flags);

	port->write_urb->transfer_buffer_length = count;
	port->write_urb->dev = port->serial->dev;

	result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
	if (result) {
		dev_dbg(&port->dev, "failed submitting write urb, error %d\n",
			result);
		priv->write_urb_in_use = 0;
		/* TODO: reschedule spcp8x5_send */
	}


	schedule_work(&port->work);
}