static int pcm_set_rate(unsigned long *rate) { unsigned long div; if (pcm_priv->pcm_device_mode == PCM_MASTER) { if (!pcm_priv) return -ENODEV; div = pcm_priv->pcmclk/(8*(*rate)) - 1; if (div >= 0 && div < 32) { __pcm_set_syndiv(div); *rate = pcm_priv->pcmclk/(8*(div+1)); pcm_priv->rate = *rate; } else *rate = pcm_priv->rate; } // __pcm_set_syndiv(div); return 0; }
static int jz_pcm_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct device *dev = dai->dev; struct jz_pcm *jz_pcm = dev_get_drvdata(dai->dev); PCM_DEBUG_MSG("enter %s, substream = %s\n", __func__, (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? "playback" : "capture"); if (!jz_pcm->pcm_mode) { clk_enable(jz_pcm->clk_gate); #if 1 __pcm_as_slaver(dev); #else clk_set_rate(jz_pcm->clk, 9600000); clk_enable(jz_pcm->clk); __pcm_as_master(dev); __pcm_set_clkdiv(dev, 9600000/20/8000 - 1); __pcm_set_syndiv(dev, 20 - 1); #endif __pcm_set_msb_one_shift_in(dev); __pcm_set_msb_one_shift_out(dev); __pcm_play_lastsample(dev); __pcm_enable(dev); __pcm_clock_enable(dev); } if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { __pcm_disable_transmit_dma(dev); __pcm_disable_replay(dev); __pcm_clear_tur(dev); jz_pcm->pcm_mode |= PCM_WRITE; } else { __pcm_disable_receive_dma(dev); __pcm_disable_record(dev); __pcm_clear_ror(dev); jz_pcm->pcm_mode |= PCM_READ; } printk("start set PCM register....\n"); return 0; }