}; EXPORT_SYMBOL_GPL(aml_i2s_dai); static const struct snd_soc_component_driver aml_component = { .name = "aml-i2s-dai", }; static int aml_i2s_dai_probe(struct platform_device *pdev) { struct aml_i2s *i2s = NULL; int ret = 0; printk(KERN_DEBUG "enter %s\n", __func__); i2s = kzalloc(sizeof(struct aml_i2s), GFP_KERNEL); if (!i2s) { dev_err(&pdev->dev, "Can't allocate aml_i2s\n"); ret = -ENOMEM; goto exit; } dev_set_drvdata(&pdev->dev, i2s); if (of_property_read_u32(pdev->dev.of_node, "clk_src_mpll", &i2s->mpll)) { printk(KERN_INFO "i2s get no clk src setting in dts, use the default mpll 0\n"); i2s->mpll = 0; } /* enable i2s MPLL and power gate first */ WRITE_MPEG_REG_BITS(MPLL_I2S_CNTL, 1, 14, 1); audio_aiu_pg_enable(1); /* enable the mclk because m8 codec need it to setup */ if (i2s->old_samplerate != 48000) { ALSA_PRINT("enterd %s,old_samplerate:%d,sample_rate=%d\n", __func__, i2s->old_samplerate, 48000);
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; unsigned int size = 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){ size = aml_i2s_hardware.buffer_bytes_max; aml_i2s_playback_start_addr = (unsigned int)buf->area; aml_i2s_playback_end_addr = (unsigned int)buf->area + size; aml_i2s_playback_phy_start_addr = buf->addr; aml_i2s_playback_phy_end_addr = buf->addr+size; } }else{ snd_soc_set_runtime_hwparams(substream, &aml_i2s_capture); if(s->device_type == AML_AUDIO_I2SIN){ size = aml_i2s_capture.buffer_bytes_max; aml_i2s_capture_start_addr = (unsigned int)buf->area; aml_i2s_capture_end_addr = (unsigned int)buf->area + size; aml_i2s_capture_phy_start_addr = buf->addr; aml_i2s_capture_phy_end_addr = buf->addr+size; } } /* 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; } // WRITE_MPEG_REG_BITS( HHI_MPLL_CNTL8, 1,14, 1); #if USE_HRTIMER == 0 prtd->timer.function = &aml_i2s_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_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->xrun_num = 0; 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; }