/* this may get called several times by oss emulation */ static int omap_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct omap_runtime_data *prtd = runtime->private_data; struct omap_pcm_dma_data *dma_data = rtd->dai->cpu_dai->dma_data; int err = 0; if (!dma_data) return -ENODEV; snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); runtime->dma_bytes = params_buffer_bytes(params); if (prtd->dma_data) return 0; prtd->dma_data = dma_data; err = omap_request_dma(dma_data->dma_req, dma_data->name, omap_pcm_dma_irq, substream, &prtd->dma_ch); if (!err && !cpu_is_omap1510()) { /* * Link channel with itself so DMA doesn't need any * reprogramming while looping the buffer */ omap_dma_link_lch(prtd->dma_ch, prtd->dma_ch); } return err; }
/* this may get called several times by oss emulation */ static int omap_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct omap_runtime_data *prtd = runtime->private_data; struct omap_pcm_dma_data *dma_data; int err = 0; dma_data = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); /* return if this is a bufferless transfer e.g. * codec <--> BT codec or GSM modem -- lg FIXME */ if (!dma_data) return 0; snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); runtime->dma_bytes = params_buffer_bytes(params); if (prtd->dma_data) return 0; prtd->dma_data = dma_data; err = omap_request_dma(dma_data->dma_req, dma_data->name, omap_pcm_dma_irq, substream, &prtd->dma_ch); if (!err) { /* * Link channel with itself so DMA doesn't need any * reprogramming while looping the buffer */ omap_dma_link_lch(prtd->dma_ch, prtd->dma_ch); } return err; }
static int abe_dbg_start_dma(struct omap_abe *abe, int circular) { struct omap_dma_channel_params dma_params; int err; /* start the DMA in either :- * * 1) circular buffer mode where the DMA will restart when it get to * the end of the buffer. * 2) default mode, where DMA stops at the end of the buffer. */ abe->debugfs.dma_req = OMAP44XX_DMA_ABE_REQ_7; err = omap_request_dma(abe->debugfs.dma_req, "ABE debug", abe_dbg_dma_irq, abe, &abe->debugfs.dma_ch); if (abe->debugfs.circular) { /* * Link channel with itself so DMA doesn't need any * reprogramming while looping the buffer */ omap_dma_link_lch(abe->debugfs.dma_ch, abe->debugfs.dma_ch); } memset(&dma_params, 0, sizeof(dma_params)); dma_params.data_type = OMAP_DMA_DATA_TYPE_S32; dma_params.trigger = abe->debugfs.dma_req; dma_params.sync_mode = OMAP_DMA_SYNC_FRAME; dma_params.src_amode = OMAP_DMA_AMODE_DOUBLE_IDX; dma_params.dst_amode = OMAP_DMA_AMODE_POST_INC; dma_params.src_or_dst_synch = OMAP_DMA_SRC_SYNC; dma_params.src_start = OMAP_ABE_D_DEBUG_FIFO_ADDR + ABE_DEFAULT_BASE_ADDRESS_L3 + ABE_DMEM_BASE_OFFSET_MPU; dma_params.dst_start = abe->debugfs.buffer_addr; dma_params.src_port = OMAP_DMA_PORT_MPUI; dma_params.src_ei = 1; dma_params.src_fi = 1 - abe->debugfs.elem_bytes; /* 128 bytes shifted into words */ dma_params.elem_count = abe->debugfs.elem_bytes >> 2; dma_params.frame_count = abe->debugfs.buffer_bytes / abe->debugfs.elem_bytes; omap_set_dma_params(abe->debugfs.dma_ch, &dma_params); omap_enable_dma_irq(abe->debugfs.dma_ch, OMAP_DMA_FRAME_IRQ); omap_set_dma_src_burst_mode(abe->debugfs.dma_ch, OMAP_DMA_DATA_BURST_16); omap_set_dma_dest_burst_mode(abe->debugfs.dma_ch, OMAP_DMA_DATA_BURST_16); abe->debugfs.reader_offset = 0; pm_runtime_get_sync(abe->dev); omap_start_dma(abe->debugfs.dma_ch); return 0; }
/*************************************************************************************** * * DMA channel requests * **************************************************************************************/ static void omap_sound_dma_link_lch(void *data) { audio_stream_t *s = (audio_stream_t *) data; int *chan = s->lch; int i; FN_IN; if (s->linked) { FN_OUT(1); return; } for (i = 0; i < nr_linked_channels; i++) { int cur_chan = chan[i]; int nex_chan = ((nr_linked_channels - 1 == i) ? chan[0] : chan[i + 1]); omap_dma_link_lch(cur_chan, nex_chan); } s->linked = 1; FN_OUT(0); }
static int __init omap1_cam_probe(struct platform_device *pdev) { struct omap1_cam_dev *pcdev; struct resource *res; struct clk *clk; void __iomem *base; unsigned int irq; int err = 0; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_irq(pdev, 0); if (!res || (int)irq <= 0) { err = -ENODEV; goto exit; } clk = clk_get(&pdev->dev, "armper_ck"); if (IS_ERR(clk)) { err = PTR_ERR(clk); goto exit; } pcdev = kzalloc(sizeof(*pcdev) + resource_size(res), GFP_KERNEL); if (!pcdev) { dev_err(&pdev->dev, "Could not allocate pcdev\n"); err = -ENOMEM; goto exit_put_clk; } pcdev->res = res; pcdev->clk = clk; pcdev->pdata = pdev->dev.platform_data; pcdev->pflags = pcdev->pdata->flags; if (pcdev->pdata) pcdev->camexclk = pcdev->pdata->camexclk_khz * 1000; switch (pcdev->camexclk) { case 6000000: case 8000000: case 9600000: case 12000000: case 24000000: break; default: dev_warn(&pdev->dev, "Incorrect sensor clock frequency %ld kHz, " "should be one of 0, 6, 8, 9.6, 12 or 24 MHz, " "please correct your platform data\n", pcdev->pdata->camexclk_khz); pcdev->camexclk = 0; case 0: dev_info(&pdev->dev, "Not providing sensor clock\n"); } INIT_LIST_HEAD(&pcdev->capture); spin_lock_init(&pcdev->lock); /* * Request the region. */ if (!request_mem_region(res->start, resource_size(res), DRIVER_NAME)) { err = -EBUSY; goto exit_kfree; } base = ioremap(res->start, resource_size(res)); if (!base) { err = -ENOMEM; goto exit_release; } pcdev->irq = irq; pcdev->base = base; sensor_reset(pcdev, true); err = omap_request_dma(OMAP_DMA_CAMERA_IF_RX, DRIVER_NAME, dma_isr, (void *)pcdev, &pcdev->dma_ch); if (err < 0) { dev_err(&pdev->dev, "Can't request DMA for OMAP1 Camera\n"); err = -EBUSY; goto exit_iounmap; } dev_dbg(&pdev->dev, "got DMA channel %d\n", pcdev->dma_ch); /* preconfigure DMA */ omap_set_dma_src_params(pcdev->dma_ch, OMAP_DMA_PORT_TIPB, OMAP_DMA_AMODE_CONSTANT, res->start + REG_CAMDATA, 0, 0); omap_set_dma_dest_burst_mode(pcdev->dma_ch, OMAP_DMA_DATA_BURST_4); /* setup DMA autoinitialization */ omap_dma_link_lch(pcdev->dma_ch, pcdev->dma_ch); err = request_irq(pcdev->irq, cam_isr, 0, DRIVER_NAME, pcdev); if (err) { dev_err(&pdev->dev, "Camera interrupt register failed\n"); goto exit_free_dma; } pcdev->soc_host.drv_name = DRIVER_NAME; pcdev->soc_host.ops = &omap1_host_ops; pcdev->soc_host.priv = pcdev; pcdev->soc_host.v4l2_dev.dev = &pdev->dev; pcdev->soc_host.nr = pdev->id; err = soc_camera_host_register(&pcdev->soc_host); if (err) goto exit_free_irq; dev_info(&pdev->dev, "OMAP1 Camera Interface driver loaded\n"); return 0; exit_free_irq: free_irq(pcdev->irq, pcdev); exit_free_dma: omap_free_dma(pcdev->dma_ch); exit_iounmap: iounmap(base); exit_release: release_mem_region(res->start, resource_size(res)); exit_kfree: kfree(pcdev); exit_put_clk: clk_put(clk); exit: return err; }