static int snd_imx_open(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct imx_pcm_runtime_data *iprtd; int ret; iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL); runtime->private_data = iprtd; init_timer(&iprtd->timer); iprtd->timer.data = (unsigned long)substream; iprtd->timer.function = imx_ssi_timer_callback; ret = snd_pcm_hw_constraint_integer(substream->runtime, SNDRV_PCM_HW_PARAM_PERIODS); if (ret < 0) return ret; snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware); return 0; }
static int snd_imx_open(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct imx_pcm_runtime_data *iprtd; int ret; iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL); if (iprtd == NULL) return -ENOMEM; runtime->private_data = iprtd; ret = snd_pcm_hw_constraint_integer(substream->runtime, SNDRV_PCM_HW_PARAM_PERIODS); if (ret < 0) { kfree(iprtd); return ret; } snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware); return 0; }
static int bf5xx_pcm_open(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; int ret = 0; snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware); ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); if (ret < 0) goto out; if (sport_handle != NULL) runtime->private_data = sport_handle; else { pr_err("sport_handle is NULL\n"); ret = -ENODEV; } out: return ret; }
static int lpass_platform_pcmops_open(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; int ret; snd_soc_set_runtime_hwparams(substream, &lpass_platform_pcm_hardware); runtime->dma_bytes = lpass_platform_pcm_hardware.buffer_bytes_max; ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); if (ret < 0) { dev_err(soc_runtime->dev, "%s() setting constraints failed: %d\n", __func__, ret); return -EINVAL; } snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); return 0; }
static int at91_pcm_open(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct at91_runtime_data *prtd; int ret = 0; snd_soc_set_runtime_hwparams(substream, &at91_pcm_hardware); /* ensure that buffer size is a multiple of period size */ ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); if (ret < 0) goto out; prtd = kzalloc(sizeof(struct at91_runtime_data), GFP_KERNEL); if (prtd == NULL) { ret = -ENOMEM; goto out; } runtime->private_data = prtd; out: return ret; }
static int hi3620_digital_open(struct snd_pcm_substream *substream) { struct hi3620_runtime_data *prtd = NULL; logd("%s : %s\n", __FUNCTION__, substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? "PLAYBACK" : "CAPTURE"); prtd = kzalloc(sizeof(struct hi3620_runtime_data), GFP_KERNEL); if (NULL == prtd) { loge("%s : kzalloc hi3620_runtime_data error!\n", __FUNCTION__); return -ENOMEM; } spin_lock_init(&prtd->lock); substream->runtime->private_data = prtd; if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) snd_soc_set_runtime_hwparams(substream, &hi3620_digital_playback); return 0; }
static int tegra_pcm_open(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct device *dev = rtd->platform->dev; struct tegra_runtime_data *prtd; int ret; if (rtd->dai_link->no_pcm) return 0; prtd = kzalloc(sizeof(struct tegra_runtime_data), GFP_KERNEL); if (prtd == NULL) return -ENOMEM; /* Set HW params now that initialization is complete */ snd_soc_set_runtime_hwparams(substream, &tegra_pcm_hardware); /* Ensure period size is multiple of 8 */ ret = snd_pcm_hw_constraint_step(substream->runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 0x8); if (ret) { dev_err(dev, "failed to set constraint %d\n", ret); kfree(prtd); return ret; } ret = snd_dmaengine_pcm_open_request_chan(substream, NULL, NULL); if (ret) { dev_err(dev, "dmaengine pcm open failed with err %d\n", ret); kfree(prtd); return ret; } snd_dmaengine_pcm_set_data(substream, prtd); return 0; }
static int omap_pcm_open(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_dmaengine_dai_dma_data *dma_data; int ret; snd_soc_set_runtime_hwparams(substream, &omap_pcm_hardware); dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); /* DT boot: filter_data is the DMA name */ if (rtd->cpu_dai->dev->of_node) { struct dma_chan *chan; chan = dma_request_slave_channel(rtd->cpu_dai->dev, dma_data->filter_data); ret = snd_dmaengine_pcm_open(substream, chan); } else { ret = snd_dmaengine_pcm_open_request_chan(substream, omap_dma_filter_fn, dma_data->filter_data); } return ret; }
static int davinci_pcm_open(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct davinci_runtime_data *prtd; int ret = 0; snd_soc_set_runtime_hwparams(substream, &davinci_pcm_hardware); prtd = kzalloc(sizeof(struct davinci_runtime_data), GFP_KERNEL); if (prtd == NULL) return -ENOMEM; spin_lock_init(&prtd->lock); runtime->private_data = prtd; ret = davinci_pcm_dma_request(substream); if (ret) { printk(KERN_ERR "davinci_pcm: Failed to get dma channels\n"); kfree(prtd); } return ret; }
static int aml_i2s_open(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct aml_runtime_data *prtd = runtime->private_data; struct snd_dma_buffer *buf = &substream->dma_buffer; audio_stream_t *s = &prtd->s; int ret = 0; ALSA_TRACE(); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { snd_soc_set_runtime_hwparams(substream, &aml_i2s_hardware); if (s->device_type == AML_AUDIO_I2SOUT) { aml_i2s_playback_start_addr = (unsigned int)buf->area; aml_i2s_playback_phy_start_addr = buf->addr; } } else { snd_soc_set_runtime_hwparams(substream, &aml_i2s_capture); if (s->device_type == AML_AUDIO_I2SIN) { aml_i2s_capture_start_addr = (unsigned int)buf->area; aml_i2s_capture_phy_start_addr = buf->addr; } } /* ensure that peroid size is a multiple of 32bytes */ ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_period_sizes); if (ret < 0) { printk("set period bytes constraint error\n"); goto out; } /* ensure that buffer size is a multiple of period size */ ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); if (ret < 0) { printk("set period error\n"); goto out; } if (!prtd) { prtd = kzalloc(sizeof(struct aml_runtime_data), GFP_KERNEL); if (prtd == NULL) { printk("alloc aml_runtime_data error\n"); ret = -ENOMEM; goto out; } prtd->substream = substream; runtime->private_data = prtd; g_prtd = prtd; printk("ml_i2s_open g_prtd %p \n", g_prtd); } else { g_prtd = prtd; } // WRITE_MPEG_REG_BITS( HHI_MPLL_CNTL8, 1,14, 1); #if USE_HRTIMER == 0 #ifndef USE_HW_TIMER prtd->timer.function = &aml_i2s_timer_callback; prtd->timer.data = (unsigned long)substream; init_timer(&prtd->timer); #else ret = snd_request_hw_timer(prtd); if (ret < 0) { printk("request audio hw timer failed \n"); goto out; } #endif #else hrtimer_init(&prtd->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); prtd->hrtimer.function = aml_i2s_hrtimer_callback; hrtimer_start(&prtd->hrtimer, ns_to_ktime(HRTIMER_PERIOD), HRTIMER_MODE_REL); printk("hrtimer inited..\n"); #endif spin_lock_init(&prtd->s.lock); s = &prtd->s; //WRITE_MPEG_REG_BITS(MPLL_I2S_CNTL, 1,14, 1); mutex_lock(&gate_mutex); if (!num_clk_gate) { num_clk_gate = 1; if (audio_gate_status == 0) { // audio_aiu_pg_enable(1); ALSA_DEBUG("aml_pcm_open device type %x \n", s->device_type); } } audio_gate_status |= s->device_type; mutex_unlock(&gate_mutex); out: return ret; }
static int tegra_pcm_open(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct tegra_runtime_data *prtd; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct tegra_pcm_dma_params * dmap; int ret = 0; prtd = kzalloc(sizeof(struct tegra_runtime_data), GFP_KERNEL); if (prtd == NULL) return -ENOMEM; runtime->private_data = prtd; prtd->substream = substream; spin_lock_init(&prtd->lock); dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); if (dmap) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { setup_dma_tx_request(&prtd->dma_req[0], dmap); setup_dma_tx_request(&prtd->dma_req[1], dmap); } else { setup_dma_rx_request(&prtd->dma_req[0], dmap); setup_dma_rx_request(&prtd->dma_req[1], dmap); } prtd->dma_req[0].dev = prtd; prtd->dma_req[1].dev = prtd; prtd->dma_chan = tegra_dma_allocate_channel( TEGRA_DMA_MODE_CONTINUOUS_SINGLE, "pcm"); if (prtd->dma_chan == NULL) { ret = -ENOMEM; goto err; } } /* Set HW params now that initialization is complete */ snd_soc_set_runtime_hwparams(substream, &tegra_pcm_hardware); /* Ensure period size is multiple of 8 */ ret = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 0x8); if (ret < 0) goto err; /* Ensure that buffer size is a multiple of period size */ ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); if (ret < 0) goto err; return 0; err: if (prtd->dma_chan) { tegra_dma_free_channel(prtd->dma_chan); } kfree(prtd); return ret; }
static int dummy_dma_open(struct snd_pcm_substream *substream) { snd_soc_set_runtime_hwparams(substream, &dummy_dma_hardware); return 0; }
int tegra_pcm_allocate(struct snd_pcm_substream *substream, int dma_mode, const struct snd_pcm_hardware *pcm_hardware) { struct snd_pcm_runtime *runtime = substream->runtime; struct tegra_runtime_data *prtd; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct tegra_pcm_dma_params * dmap; int ret = 0; int i = 0; prtd = kzalloc(sizeof(struct tegra_runtime_data), GFP_KERNEL); if (prtd == NULL) return -ENOMEM; runtime->private_data = prtd; prtd->substream = substream; spin_lock_init(&prtd->lock); dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); prtd->dma_req_count = MAX_DMA_REQ_COUNT; if (dmap) { for (i = 0; i < prtd->dma_req_count; i++) prtd->dma_req[i].dev = prtd; prtd->dma_chan = tegra_dma_allocate_channel( dma_mode, "pcm"); if (prtd->dma_chan == NULL) { ret = -ENOMEM; goto err; } } /* Set HW params now that initialization is complete */ snd_soc_set_runtime_hwparams(substream, pcm_hardware); /* Ensure period size is multiple of 8 */ ret = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 0x8); if (ret < 0) goto err; /* Ensure that buffer size is a multiple of period size */ ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); if (ret < 0) goto err; return 0; err: if (prtd->dma_chan) { tegra_dma_free_channel(prtd->dma_chan); } kfree(prtd); return ret; }
static int hi3630_srcup_normal_open(struct snd_pcm_substream *substream) { struct hi3630_srcup_runtime_data *prtd = NULL; struct snd_soc_pcm_runtime *rtd = NULL; struct hi3630_srcup_data *pdata = NULL; struct snd_pcm *pcm = substream->pcm; int ret = 0; BUG_ON(NULL == pcm); prtd = kzalloc(sizeof(struct hi3630_srcup_runtime_data), GFP_KERNEL); if (NULL == prtd) { loge("kzalloc hi3630_srcup_runtime_data error!\n"); return -ENOMEM; } mutex_init(&prtd->mutex); spin_lock_init(&prtd->lock); rtd = (struct snd_soc_pcm_runtime *)substream->private_data; pdata = (struct hi3630_srcup_data *)snd_soc_platform_get_drvdata(rtd->platform); BUG_ON(NULL == pdata); prtd->pdata = pdata; substream->runtime->private_data = prtd; #ifdef SRCUP_ENABLE #ifdef CONFIG_PM_RUNTIME pm_runtime_get_sync(pdata->dev); #else ret = regulator_bulk_enable(1, &pdata->regu); if (0 != ret) { loge("couldn't enable regulators %d\n", ret); goto err_bulk; } #endif srcup_module_enable(true); ret = request_irq(pdata->irq, hi3630_intr_src_up_handle, IRQF_SHARED, "asp_irq_srcup_normal", pcm); if (0 > ret) { loge("request irq error, error No. = %d\n", ret); goto err_irq; } enable_srcup_interrupeter(true); #endif ret = snd_soc_set_runtime_hwparams(substream, &hi3630_srcup_normal_hardware); return ret; #ifdef SRCUP_ENABLE err_irq: srcup_module_enable(false); #ifdef CONFIG_PM_RUNTIME pm_runtime_mark_last_busy(pdata->dev); pm_runtime_put_autosuspend(pdata->dev); #else regulator_bulk_disable(1, &prtd->pdata->regu); err_bulk: #endif kfree(prtd); return ret; #endif }
static int aml_pcm_open(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct aml_runtime_data *prtd = NULL; int ret = 0; void *buffer = NULL; unsigned int buffersize = 0; audio_stream_t *s = NULL; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){ playback_substream_handle = (unsigned long)substream; snd_soc_set_runtime_hwparams(substream, &aml_pcm_hardware); buffersize = aml_pcm_hardware.period_bytes_max; }else{ snd_soc_set_runtime_hwparams(substream, &aml_pcm_capture); buffersize = aml_pcm_capture.period_bytes_max; } /* ensure that peroid size is a multiple of 32bytes */ ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_period_sizes); if (ret < 0) { printk("set period bytes constraint error\n"); goto out; } /* ensure that buffer size is a multiple of period size */ ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); if (ret < 0) { printk("set period error\n"); goto out; } prtd = kzalloc(sizeof(struct aml_runtime_data), GFP_KERNEL); if (prtd == NULL) { printk("alloc aml_runtime_data error\n"); ret = -ENOMEM; goto out; } prtd->substream = substream; runtime->private_data = prtd; if(!prtd->buf){ buffer = kzalloc(buffersize, GFP_KERNEL); if (buffer==NULL){ printk("alloc aml_runtime_data buffer error\n"); kfree(prtd); ret = -ENOMEM; goto out; } prtd->buf = buffer; } #if USE_HRTIMER == 0 prtd->timer.function = &aml_pcm_timer_callback; prtd->timer.data = (unsigned long)substream; init_timer(&prtd->timer); #else hrtimer_init(&prtd->hrtimer,CLOCK_MONOTONIC, HRTIMER_MODE_REL); prtd->hrtimer.function = aml_pcm_hrtimer_callback; hrtimer_start(&prtd->hrtimer, ns_to_ktime(HRTIMER_PERIOD), HRTIMER_MODE_REL); printk("hrtimer inited..\n"); #endif spin_lock_init(&prtd->s.lock); s = &prtd->s; s->xrun_num = 0; out: return ret; }
static int ux500_pcm_open(struct snd_pcm_substream *substream) { int stream_id = substream->pstr->stream; struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *dai = rtd->cpu_dai; struct device *dev = dai->dev; int ret; struct ux500_msp_dma_params *dma_params; u16 per_data_width, mem_data_width; struct stedma40_chan_cfg *dma_cfg; dev_dbg(dev, "%s: MSP %d (%s): Enter.\n", __func__, dai->id, snd_pcm_stream_str(substream)); dev_dbg(dev, "%s: Set runtime hwparams.\n", __func__); if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) snd_soc_set_runtime_hwparams(substream, &ux500_pcm_hw_playback); else snd_soc_set_runtime_hwparams(substream, &ux500_pcm_hw_capture); /* ensure that buffer size is a multiple of period size */ ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); if (ret < 0) { dev_err(dev, "%s: Error: snd_pcm_hw_constraints failed (%d)\n", __func__, ret); return ret; } dev_dbg(dev, "%s: Set hw-struct for %s.\n", __func__, snd_pcm_stream_str(substream)); runtime->hw = (stream_id == SNDRV_PCM_STREAM_PLAYBACK) ? ux500_pcm_hw_playback : ux500_pcm_hw_capture; mem_data_width = STEDMA40_HALFWORD_WIDTH; dma_params = snd_soc_dai_get_dma_data(dai, substream); switch (dma_params->data_size) { case 32: per_data_width = STEDMA40_WORD_WIDTH; break; case 16: per_data_width = STEDMA40_HALFWORD_WIDTH; break; case 8: per_data_width = STEDMA40_BYTE_WIDTH; break; default: per_data_width = STEDMA40_WORD_WIDTH; dev_warn(rtd->platform->dev, "%s: Unknown data-size (%d)! Assuming 32 bits.\n", __func__, dma_params->data_size); } dma_cfg = dma_params->dma_cfg; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { dma_cfg->src_info.data_width = mem_data_width; dma_cfg->dst_info.data_width = per_data_width; } else { dma_cfg->src_info.data_width = per_data_width; dma_cfg->dst_info.data_width = mem_data_width; } ret = snd_dmaengine_pcm_open(substream, stedma40_filter, dma_cfg); if (ret) { dev_dbg(dai->dev, "%s: ERROR: snd_dmaengine_pcm_open failed (%d)!\n", __func__, ret); return ret; } snd_dmaengine_pcm_set_data(substream, dma_cfg); return 0; }
static int lpc313x_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { struct snd_pcm_runtime *rtd = substream->runtime; struct lpc313x_dma_data *prtd = rtd->private_data; int ret = 0; #if defined (CONFIG_SND_USE_DMA_LINKLIST) int i, tch; u32 addr; dma_sg_ll_t *p_sg_cpuw, *p_sg_dmaw; unsigned long timeout; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { tch = 0; } else { tch = 1; } switch (cmd) { case SNDRV_PCM_TRIGGER_START: prtd->dma_cur = prtd->dma_buffer; p_sg_cpuw = prtd->p_sg_cpu; p_sg_dmaw = prtd->p_sg_dma; /* Build a linked list that wraps around */ addr = (u32) prtd->dma_buffer; for (i = 0; i < prtd->num_periods; i++) { p_sg_cpuw->setup.trans_length = (prtd->period_size / 4) - 1; p_sg_cpuw->setup.cfg = prtd->dma_cfg_base; p_sg_cpuw->next_entry = (u32) (p_sg_dmaw + 1); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { p_sg_cpuw->setup.src_address = addr; p_sg_cpuw->setup.dest_address = TX_FIFO_ADDR; } else { p_sg_cpuw->setup.dest_address = addr; p_sg_cpuw->setup.src_address = RX_FIFO_ADDR; } /* Wrap end of list back to start? */ if (i == (prtd->num_periods - 1)) p_sg_cpuw->next_entry = (u32) prtd->p_sg_dma; p_sg_cpuw++; p_sg_dmaw++; addr += prtd->period_size; } /* Add and start audio data position timer */ init_timer(&prtd->timer[tch]); prtd->timer[tch].data = (unsigned long) substream; prtd->timer[tch].function = lpc313x_check_dmall; prtd->timer[tch].expires = jiffies + MINTICKINC; add_timer(&prtd->timer[tch]); /* Program DMA channel and start it */ dma_prog_sg_channel(prtd->dmach, (u32) prtd->p_sg_dma); dma_set_irq_mask(prtd->dmach, 1, 1); #else dma_setup_t dmasetup; switch (cmd) { case SNDRV_PCM_TRIGGER_START: prtd->dma_cur = prtd->dma_buffer; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { dmasetup.src_address = (u32) prtd->dma_buffer; dmasetup.dest_address = TX_FIFO_ADDR; } else { dmasetup.dest_address = (u32) prtd->dma_buffer; dmasetup.src_address = RX_FIFO_ADDR; } dmasetup.cfg = prtd->dma_cfg_base; dmasetup.trans_length = (2 * prtd->period_size / 4) - 1; /* Program DMA channel and start it */ dma_prog_channel(prtd->dmach, &dmasetup); dma_set_irq_mask(prtd->dmach, 0, 0); #endif dma_start_channel(prtd->dmach); break; case SNDRV_PCM_TRIGGER_STOP: #if defined (CONFIG_SND_USE_DMA_LINKLIST) del_timer_sync(&prtd->timer[tch]); #endif /* Stop the companion channel and let the current DMA transfer finish */ dma_stop_channel_sg(prtd->dmach); timeout = jiffies + (HZ / 20); while ((dma_channel_enabled(prtd->dmach)) && (jiffies < timeout)) { cpu_relax(); } // dma_stop_channel(prtd->dmach); break; case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: break; default: ret = -EINVAL; } return ret; } static snd_pcm_uframes_t lpc313x_pcm_pointer(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct lpc313x_dma_data *prtd = runtime->private_data; snd_pcm_uframes_t x; /* Return an offset into the DMA buffer for the next data */ x = bytes_to_frames(runtime, (prtd->dma_cur - runtime->dma_addr)); if (x >= runtime->buffer_size) x = 0; return x; } static int lpc313x_pcm_open(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct lpc313x_dma_data *prtd; int ret = 0; snd_soc_set_runtime_hwparams(substream, &lpc313x_pcm_hardware); /* ensure that buffer size is a multiple of period size */ ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); if (ret < 0) goto out; prtd = kzalloc(sizeof(*prtd), GFP_KERNEL); if (prtd == NULL) { ret = -ENOMEM; goto out; } runtime->private_data = prtd; prtd->dmach = -1; out: return ret; } static int lpc313x_pcm_close(struct snd_pcm_substream *substream) { struct lpc313x_dma_data *prtd = substream->runtime->private_data; kfree(prtd); return 0; } static int lpc313x_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma) { struct snd_pcm_runtime *runtime = substream->runtime; return dma_mmap_writecombine(substream->pcm->card->dev, vma, runtime->dma_area, runtime->dma_addr, runtime->dma_bytes); } static struct snd_pcm_ops lpc313x_pcm_ops = { .open = lpc313x_pcm_open, .close = lpc313x_pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = lpc313x_pcm_hw_params, .hw_free = lpc313x_pcm_hw_free, .prepare = lpc313x_pcm_prepare, .trigger = lpc313x_pcm_trigger, .pointer = lpc313x_pcm_pointer, .mmap = lpc313x_pcm_mmap, }; /* * ASoC platform driver */ static int lpc313x_pcm_new(struct snd_card *card, struct snd_soc_dai *dai, struct snd_pcm *pcm) { int ret = 0; if (!card->dev->dma_mask) card->dev->dma_mask = &lpc313x_pcm_dmamask; if (!card->dev->coherent_dma_mask) card->dev->coherent_dma_mask = 0xffffffff; if (dai->playback.channels_min) { ret = lpc313x_pcm_allocate_dma_buffer( pcm, SNDRV_PCM_STREAM_PLAYBACK); if (ret) goto out; } if (dai->capture.channels_min) { pr_debug("%s: Allocating PCM capture DMA buffer\n", SND_NAME); ret = lpc313x_pcm_allocate_dma_buffer( pcm, SNDRV_PCM_STREAM_CAPTURE); if (ret) goto out; } out: return ret; }
static int tegra_pcm_open(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm *pcm = substream->pcm; struct pcm_runtime_data *prtd; int ret = 0; NvError e = NvSuccess; NvAudioFxMessage message; NvAudioFxObjectHandle hSource = 0; struct tegra_audio_data *ptscx = tegra_snd_cx[pcm->device]; prtd = kzalloc(sizeof(struct pcm_runtime_data), GFP_KERNEL); if (prtd == NULL) return -ENOMEM; runtime->private_data = prtd; snd_soc_set_runtime_hwparams(substream, &tegra_pcm_hardware); spin_lock_init(&prtd->lock); prtd->timeout = INIT_TIMEOUT; prtd->stdoutpath = 0; prtd->stdinpath = 0; prtd->state = NVALSA_INVALID_STATE; prtd->stream = substream->stream; if (!ptscx->mixer_handle) { ret = tegra_audiofx_init(ptscx); if (ret) goto fail; } init_completion(&prtd->thread_comp); init_waitqueue_head(&prtd->buf_wait); sema_init(&prtd->buf_done_sem, 0); sema_init(&prtd->stop_done_sem, 0); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){ hSource = ptscx->i2s1_play_mix; if (pcm->device == I2S2) hSource = ptscx->i2s2_play_mix; prtd->mixer_buffer = ptscx->mixer_buffer[0]; prtd->stdoutpath = (StandardPath*)kzalloc(sizeof(StandardPath), GFP_KERNEL); if (prtd->stdoutpath == NULL) { snd_printk(KERN_ERR "pcm_open kzalloc failed \n"); ret = -ENOMEM; goto fail; } e = tegra_audiofx_create_output(ptscx->m_hRm, ptscx->mixer_handle, prtd->stdoutpath, hSource); if (e != NvSuccess) { snd_printk(KERN_ERR "audiofx_create_output failed \n"); ret = -EFAULT; goto fail; } memset(&message, 0, sizeof(NvAudioFxMessage)); message.Event = (NvAudioFxEventBufferDone | NvAudioFxEventStateChange); message.hFx = (NvAudioFxHandle)prtd->stdoutpath->Stream; message.pContext = prtd; e = ptscx->xrt_fxn.SetProperty( (NvAudioFxObjectHandle)ptscx->m_FxNotifier.hNotifier, NvAudioFxIoProperty_AddEvent, sizeof(NvAudioFxMessage), &message); if (e != NvSuccess) { snd_printk(KERN_ERR "TransportSetProperty failed\n"); ret = -EFAULT; goto fail; } ptscx->m_FxNotifier.Event |= (NvAudioFxEventBufferDone | NvAudioFxEventStateChange); prtd->play_thread = kthread_run(play_thread, substream, "%sthread", "play"); if (IS_ERR(prtd->play_thread)) { snd_printk(KERN_ERR "KTHREAD RUN FAIL\n"); ret = PTR_ERR(prtd->play_thread); goto fail; } } else { hSource = ptscx->i2s1_rec_split; if (pcm->device == I2S2) hSource = ptscx->i2s2_rec_split; prtd->mixer_buffer = ptscx->mixer_buffer[1]; prtd->stdinpath = (StandardPath*)kzalloc(sizeof(StandardPath), GFP_KERNEL); if (prtd->stdinpath == NULL) { snd_printk(KERN_ERR "pcm_open kzalloc failed \n"); ret = -ENOMEM; goto fail; } e = tegra_audiofx_create_input(ptscx->m_hRm, ptscx->mixer_handle, prtd->stdinpath, NvAudioInputSelect_Record, hSource); if (e != NvSuccess) { snd_printk(KERN_ERR "audiofx_create_input failed \n"); ret = -EFAULT; goto fail; } memset(&message, 0, sizeof(NvAudioFxMessage)); message.Event = (NvAudioFxEventBufferDone | NvAudioFxEventStateChange); message.hFx = (NvAudioFxHandle)prtd->stdinpath->Stream; message.pContext = prtd; e = ptscx->xrt_fxn.SetProperty( (NvAudioFxObjectHandle)ptscx->m_FxNotifier.hNotifier, NvAudioFxIoProperty_AddEvent, sizeof(NvAudioFxMessage), &message); if (e != NvSuccess) { snd_printk(KERN_ERR "TransportSetProperty failed\n"); ret = -EFAULT; goto fail; } ptscx->m_FxNotifier.Event |= (NvAudioFxEventBufferDone | NvAudioFxEventStateChange); prtd->rec_thread = kthread_run(rec_thread, substream, "%sthread", "rec" ); if (IS_ERR(prtd->rec_thread)) { snd_printk(KERN_ERR "Kthread Run Fail\n"); ret = PTR_ERR(prtd->rec_thread); goto fail; } } if (pcm->device == I2S2) { NvAudioFxIoDevice io_device; mutex_lock(&tegra_audio_state.mutex_lock); tegra_audio_state.audio_mode |= NvAudioFxMode_Bluetooth_Sco; tegra_audio_state.devices_available |= NvAudioFxIoDevice_Bluetooth_Sco; mutex_unlock(&tegra_audio_state.mutex_lock); ptscx->xrt_fxn.SetProperty( (NvAudioFxObjectHandle)ptscx->mixer_handle, NvAudioFxMixerProperty_ModeSelect, sizeof(NvAudioFxMode), &tegra_audio_state.audio_mode); ptscx->xrt_fxn.SetProperty(ptscx->mi2s1, NvAudioFxIoProperty_OutputAvailable, sizeof(NvAudioFxIoDevice), &tegra_audio_state.devices_available); ptscx->xrt_fxn.SetProperty(ptscx->mi2s1, NvAudioFxIoProperty_InputAvailable, sizeof(NvAudioFxIoDevice), &tegra_audio_state.devices_available); io_device = NvAudioFxIoDevice_Bluetooth_Sco; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { ptscx->xrt_fxn.SetProperty(ptscx->mi2s1, NvAudioFxIoProperty_OutputEnable, sizeof(NvAudioFxIoDevice), &io_device); } else { ptscx->xrt_fxn.SetProperty(ptscx->mi2s1, NvAudioFxIoProperty_InputEnable, sizeof(NvAudioFxIoDevice), &io_device); } } return ret; fail: snd_printk(KERN_ERR "tegra_pcm_open - failed \n"); pcm_common_close(substream); return ret; }
static int bcm947xx_pcm_open(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; bcm947xx_i2s_info_t *snd_bcm = rtd->dai->cpu_dai->private_data; struct snd_pcm_runtime *runtime = substream->runtime; struct bcm947xx_runtime_data *brtd; int ret; DBG("%s %s\n", __FUNCTION__, bcm947xx_direction_str(substream)); if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { snd_soc_set_runtime_hwparams(substream, &bcm947xx_pcm_hardware_capture); } else { snd_soc_set_runtime_hwparams(substream, &bcm947xx_pcm_hardware_playback); } if (snd_bcm->in_use & ~(1 << substream->stream)) { /* Another stream is in-use; set our constraints to match. */ if ((ret = bcm947xx_pcm_set_constraints(runtime, snd_bcm)) < 0) return ret; } brtd = kzalloc(sizeof(struct bcm947xx_runtime_data), GFP_KERNEL); if (brtd == NULL) { return -ENOMEM; } spin_lock_init(&brtd->lock); runtime->private_data = brtd; /* probably should put this somewhere else, after setting up isr ??? */ /* Enable appropriate channel. */ /* Channel dma_XXXinit needs to be called before descriptors can be * posted to the DMA. Posting currently occurs in the copy operator, * which is called after prepare but before trigger(start). */ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { dma_rxreset(snd_bcm->di[0]); dma_rxinit(snd_bcm->di[0]); } else { dma_txreset(snd_bcm->di[0]); dma_txinit(snd_bcm->di[0]); if (BCM947XX_DMA_LOOPBACK_ENABLED) dma_fifoloopbackenable(snd_bcm->di[0]); // dma_txsuspend(snd_bcm->di[0]); } if (BCM947XX_PCM_DEBUG_ON) { DBG("%s: i2s devcontrol 0x%x devstatus 0x%x\n", __FUNCTION__, R_REG(snd_bcm->osh, &snd_bcm->regs->devcontrol), R_REG(snd_bcm->osh, &snd_bcm->regs->devstatus)); DBG("%s: i2s intstatus 0x%x intmask 0x%x\n", __FUNCTION__, R_REG(snd_bcm->osh, &snd_bcm->regs->intstatus), R_REG(snd_bcm->osh, &snd_bcm->regs->intmask)); DBG("%s: i2s control 0x%x\n", __FUNCTION__, R_REG(snd_bcm->osh, &snd_bcm->regs->i2scontrol)); DBG("%s: i2s clkdivider 0x%x txplayth 0x%x\n", __FUNCTION__, R_REG(snd_bcm->osh, &snd_bcm->regs->clkdivider), R_REG(snd_bcm->osh, &snd_bcm->regs->txplayth)); DBG("%s: i2s stxctrl 0x%x\n", __FUNCTION__, R_REG(snd_bcm->osh, &snd_bcm->regs->stxctrl)); { uint32 temp; temp = R_REG(snd_bcm->osh, &snd_bcm->regs->fifocounter); DBG("%s: i2s txcnt 0x%x rxcnt 0x%x\n", __FUNCTION__, (temp & I2S_FC_TX_CNT_MASK)>> I2S_FC_TX_CNT_SHIFT, (temp & I2S_FC_RX_CNT_MASK)>> I2S_FC_RX_CNT_SHIFT); } } return 0; }