static int jz_dmic_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct device *dev = dai->dev; struct jz_dmic *jz_dmic = dev_get_drvdata(dai->dev); DMIC_DEBUG_MSG("enter %s, substream capture\n",__func__); if (!jz_dmic->dmic_mode) { __dmic_enable(dev); } if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { jz_dmic->dmic_mode |= DMIC_READ; } else { dev_err(dai->dev, "dmic is a capture device\n"); return -EINVAL; } clk_enable(jz_dmic->clk_gate_dmic); regulator_enable(jz_dmic->vcc_dmic); jz_dmic->en = 1; // dump_registers(jz_dmic->dev); printk("start set dmic register....\n"); return 0; }
static int jz_dmic_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { struct jz_pcm_runtime_data *prtd = substream->runtime->private_data; DMIC_DEBUG_MSG("enter %s, substream capture cmd = %d\n", __func__,cmd); switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: #ifndef CONFIG_JZ_ASOC_DMA_HRTIMER_MODE if (atomic_read(&prtd->stopped_pending)) return -EPIPE; #endif printk(KERN_DEBUG"dmic start\n"); jz_dmic_start_substream(substream, dai); break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: #ifndef CONFIG_JZ_ASOC_DMA_HRTIMER_MODE if (atomic_read(&prtd->stopped_pending)) return 0; #endif printk(KERN_DEBUG"dmic stop\n"); jz_dmic_stop_substream(substream, dai); break; } return 0; }
static void jz_dmic_start_substream(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct device *dev = dai->dev; DMIC_DEBUG_MSG("enter %s, substream start capture\n", __func__); if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { __dmic_enable_rdms(dev); __dmic_enable(dev); } else { dev_err(dai->dev, "DMIC is a capture device\n"); } return; }
static void jz_dmic_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct jz_dmic *jz_dmic = dev_get_drvdata(dai->dev); struct device *dev = dai->dev; DMIC_DEBUG_MSG("enter %s, substream = capture\n", __func__); jz_dmic_stop_substream(substream, dai); if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) jz_dmic->dmic_mode &= ~DMIC_READ; if (!jz_dmic->dmic_mode) { __dmic_disable(dev); } regulator_disable(jz_dmic->vcc_dmic); clk_disable(jz_dmic->clk_gate_dmic); jz_dmic->en = 0; return; }
static int jz_dmic_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { struct device *dev = dai->dev; int channels = params_channels(params); int rate = params_rate(params); struct jz_dmic *jz_dmic = dev_get_drvdata(dai->dev); int fmt_width = snd_pcm_format_width(params_format(params)); enum dma_slave_buswidth buswidth; int trigger; DMIC_DEBUG_MSG("enter %s, substream = %s\n",__func__,"capture"); if (!((1 << params_format(params)) & JZ_DMIC_FORMATS) ||channels < 1||channels > 4|| rate > 48000||rate < 8000 ||fmt_width != 16) { dev_err(dai->dev, "hw params not inval channel %d params %x rate %d fmt_width %d\n", channels, params_format(params),rate,fmt_width); return -EINVAL; } if (jz_dmic->unpack_enable) buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES; else buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES; if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { jz_dmic->rx_dma_data.buswidth = buswidth; jz_dmic->rx_dma_data.max_burst = (DMIC_FIFO_DEPTH * buswidth)/2; trigger = jz_dmic->rx_dma_data.max_burst/(int)buswidth; __dmic_set_request(dev, trigger); __dmic_set_chnum(dev, channels - 1); dmic_set_rate(dev,rate); snd_soc_dai_set_dma_data(dai, substream, (void *)&jz_dmic->rx_dma_data); } else { dev_err(dai->dev, "DMIC is a capture device\n"); } return 0; }