|
@@ -972,3 +972,96 @@ static int s3c2410_dma_started(struct s3c2410_dma_chan *chan)
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
+
|
|
|
+int
|
|
|
+s3c2410_dma_ctrl(enum dma_ch channel, enum s3c2410_chan_op op)
|
|
|
+{
|
|
|
+ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
|
|
|
+
|
|
|
+ if (chan == NULL)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ switch (op) {
|
|
|
+ case S3C2410_DMAOP_START:
|
|
|
+ return s3c2410_dma_start(chan);
|
|
|
+
|
|
|
+ case S3C2410_DMAOP_STOP:
|
|
|
+ return s3c2410_dma_dostop(chan);
|
|
|
+
|
|
|
+ case S3C2410_DMAOP_PAUSE:
|
|
|
+ case S3C2410_DMAOP_RESUME:
|
|
|
+ return -ENOENT;
|
|
|
+
|
|
|
+ case S3C2410_DMAOP_FLUSH:
|
|
|
+ return s3c2410_dma_flush(chan);
|
|
|
+
|
|
|
+ case S3C2410_DMAOP_STARTED:
|
|
|
+ return s3c2410_dma_started(chan);
|
|
|
+
|
|
|
+ case S3C2410_DMAOP_TIMEOUT:
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ return -ENOENT; /* unknown, don't bother */
|
|
|
+}
|
|
|
+
|
|
|
+EXPORT_SYMBOL(s3c2410_dma_ctrl);
|
|
|
+
|
|
|
+/* DMA configuration for each channel
|
|
|
+ *
|
|
|
+ * DISRCC -> source of the DMA (AHB,APB)
|
|
|
+ * DISRC -> source address of the DMA
|
|
|
+ * DIDSTC -> destination of the DMA (AHB,APD)
|
|
|
+ * DIDST -> destination address of the DMA
|
|
|
+*/
|
|
|
+
|
|
|
+/* s3c2410_dma_config
|
|
|
+ *
|
|
|
+ * xfersize: size of unit in bytes (1,2,4)
|
|
|
+*/
|
|
|
+
|
|
|
+int s3c2410_dma_config(enum dma_ch channel,
|
|
|
+ int xferunit)
|
|
|
+{
|
|
|
+ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
|
|
|
+ unsigned int dcon;
|
|
|
+
|
|
|
+ pr_debug("%s: chan=%d, xfer_unit=%d\n", __func__, channel, xferunit);
|
|
|
+
|
|
|
+ if (chan == NULL)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ dcon = chan->dcon & dma_sel.dcon_mask;
|
|
|
+ pr_debug("%s: dcon is %08x\n", __func__, dcon);
|
|
|
+
|
|
|
+ switch (chan->req_ch) {
|
|
|
+ case DMACH_I2S_IN:
|
|
|
+ case DMACH_I2S_OUT:
|
|
|
+ case DMACH_PCM_IN:
|
|
|
+ case DMACH_PCM_OUT:
|
|
|
+ case DMACH_MIC_IN:
|
|
|
+ default:
|
|
|
+ dcon |= S3C2410_DCON_HANDSHAKE;
|
|
|
+ dcon |= S3C2410_DCON_SYNC_PCLK;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case DMACH_SDI:
|
|
|
+ /* note, ensure if need HANDSHAKE or not */
|
|
|
+ dcon |= S3C2410_DCON_SYNC_PCLK;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case DMACH_XD0:
|
|
|
+ case DMACH_XD1:
|
|
|
+ dcon |= S3C2410_DCON_HANDSHAKE;
|
|
|
+ dcon |= S3C2410_DCON_SYNC_HCLK;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ switch (xferunit) {
|
|
|
+ case 1:
|
|
|
+ dcon |= S3C2410_DCON_BYTE;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 2:
|
|
|
+ dcon |= S3C2410_DCON_HALFWORD;
|