From: ChenJQ Date: Mon, 11 Apr 2011 09:29:09 +0000 (-0700) Subject: 解决录音与放音不能同时开启问题 X-Git-Tag: firefly_0821_release~10518 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=b56a480b4881e55cec437c376be4f008fd95ed08;p=firefly-linux-kernel-4.4.55.git 解决录音与放音不能同时开启问题 --- diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index 0bd70dfa6d32..2551e7e09618 100755 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c @@ -221,7 +221,7 @@ static int wm8900_hp_event(struct snd_soc_dapm_widget *w, struct snd_soc_codec *codec = w->codec; u16 hpctl1 = snd_soc_read(codec, WM8900_REG_HPCTL1); - WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__); + WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__); switch (event) { case SND_SOC_DAPM_PRE_PMU: @@ -637,7 +637,7 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm8900_add_widgets(struct snd_soc_codec *codec) { - WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__); + WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__); snd_soc_dapm_new_controls(codec, wm8900_dapm_widgets, ARRAY_SIZE(wm8900_dapm_widgets)); @@ -649,13 +649,13 @@ static int wm8900_add_widgets(struct snd_soc_codec *codec) static void wm8900_set_hw(struct snd_soc_codec *codec) { - printk("Enter:%s, %d \n", __FUNCTION__, __LINE__); + WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__); snd_soc_write(codec, WM8900_REG_HPCTL1, 0x30); snd_soc_write(codec, WM8900_REG_POWER1, 0x0100); snd_soc_write(codec, WM8900_REG_POWER3, 0x60); snd_soc_write(codec, WM8900_REG_POWER1, 0x0101); - msleep(400); + msleep(300); snd_soc_write(codec, WM8900_REG_POWER1, 0x0109); snd_soc_write(codec, WM8900_REG_ADDCTL, 0x02); snd_soc_write(codec, WM8900_REG_POWER1, 0x09); @@ -688,11 +688,6 @@ static void wm8900_set_hw(struct snd_soc_codec *codec) snd_soc_write(codec, WM8900_REG_INBOOSTMIX1, 0x0042); snd_soc_write(codec, WM8900_REG_INBOOSTMIX2, 0x0042); snd_soc_write(codec, WM8900_REG_ADCPATH, 0x0055); - - //open SPK control GPIO - gpio_request(SPK_CON, NULL); - gpio_direction_output(SPK_CON,GPIO_HIGH); - gpio_free(SPK_CON); } static int wm8900_hw_params(struct snd_pcm_substream *substream, @@ -704,7 +699,7 @@ static int wm8900_hw_params(struct snd_pcm_substream *substream, struct snd_soc_codec *codec = socdev->card->codec; u16 reg; - WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__); + WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__); reg = snd_soc_read(codec, WM8900_REG_AUDIO1) & ~0x60; @@ -751,7 +746,7 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref, BUG_ON(!Fout); - WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__); + WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__); /* The FLL must run at 90-100MHz which is then scaled down to * the output value by FLLCLK_DIV. */ @@ -815,7 +810,7 @@ static int wm8900_set_fll(struct snd_soc_codec *codec, struct _fll_div fll_div; unsigned int reg; - WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__); + WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__); if (wm8900->fll_in == freq_in && wm8900->fll_out == freq_out) return 0; @@ -893,7 +888,7 @@ static int wm8900_set_dai_clkdiv(struct snd_soc_dai *codec_dai, { struct snd_soc_codec *codec = codec_dai->codec; unsigned int reg; - WM8900_DBG("Enter:%s, %d, div_id=%d, div=%d \n", __FUNCTION__, __LINE__, div_id, div); + WM8900_DBG("Enter:%s, %d, div_id=%d, div=%d \n", __FUNCTION__, __LINE__, div_id, div); switch (div_id) { case WM8900_BCLK_DIV: @@ -945,7 +940,7 @@ static int wm8900_set_dai_fmt(struct snd_soc_dai *codec_dai, struct snd_soc_codec *codec = codec_dai->codec; unsigned int clocking1, aif1, aif3, aif4; - WM8900_DBG("Enter:%s, %d, fmt=0x%08X \n", __FUNCTION__, __LINE__, fmt); + WM8900_DBG("Enter:%s, %d, fmt=0x%08X \n", __FUNCTION__, __LINE__, fmt); clocking1 = snd_soc_read(codec, WM8900_REG_CLOCKING1); aif1 = snd_soc_read(codec, WM8900_REG_AUDIO1); @@ -1072,51 +1067,84 @@ static int wm8900_digital_mute(struct snd_soc_dai *codec_dai, int mute) return 0; } -static int wm8900_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *codec_dai) +static int wm8900_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_card *card = socdev->card; - struct snd_soc_codec *codec = card->codec; - - printk("wm8900_shutdown \n"); + struct snd_soc_dai_link *machine = rtd->dai; + struct snd_soc_dai *codec_dai = machine->codec_dai; + struct snd_soc_codec *codec = socdev->card->codec; - snd_soc_write(codec, WM8900_REG_RESET, 0); + WM8900_DBG("Enter::%s----%d substream->stream:%s \n",__FUNCTION__,__LINE__, + substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? "PLAYBACK":"CAPTURE"); - //open SPK control GPIO - gpio_request(SPK_CON, NULL); - gpio_direction_output(SPK_CON,GPIO_LOW); - gpio_free(SPK_CON); + if (!(codec_dai->playback.active || codec_dai->capture.active)) { + WM8900_DBG("Power up wm8900\n"); + wm8900_set_hw(codec); + } return 0; } -static int wm8900_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *codec_dai) +static void wm8900_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_card *card = socdev->card; - struct snd_soc_codec *codec = card->codec; + struct snd_soc_dai_link *machine = rtd->dai; + struct snd_soc_dai *codec_dai = machine->codec_dai; + struct snd_soc_codec *codec = socdev->card->codec; + + WM8900_DBG("Enter::%s----%d substream->stream:%s \n",__FUNCTION__,__LINE__, + substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? "PLAYBACK":"CAPTURE"); - printk("wm8900_prepare \n"); + /* If */ + if (!codec_dai->capture.active && !codec_dai->playback.active && + (substream->stream == SNDRV_PCM_STREAM_CAPTURE)) { - wm8900_set_hw(codec); + msleep(200); + } - return 0; + if (!codec_dai->capture.active && !codec_dai->playback.active) { + + WM8900_DBG("Power down wm8900\n"); + + /* When codec is not using , close it. */ + snd_soc_write(codec, WM8900_REG_RESET, 0); + } } -#ifdef CONFIG_MACH_RK29_MALATA -static int wm8900_trigger(struct snd_pcm_substream *substream, int trigger) +static int wm8900_trigger(struct snd_pcm_substream *substream, + int status, + struct snd_soc_dai *dai) { - WM8900_DBG("Enter::%s----%d trigger = %d\n",__FUNCTION__,__LINE__, trigger); - if(trigger == 1){ - gpio_set_value(SPK_CON, GPIO_HIGH); - } else{ - gpio_set_value(SPK_CON, GPIO_LOW); - } + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai_link *machine = rtd->dai; + struct snd_soc_dai *codec_dai = machine->codec_dai; + + WM8900_DBG("Enter::%s----%d status = %d substream->stream:%s \n",__FUNCTION__, __LINE__, status, + substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? "PLAYBACK":"CAPTURE"); + + if(status == 1 || status == 0){ + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){ + + codec_dai->playback.active = status; +#ifdef SPK_CON + if(status == 1){ + gpio_set_value(SPK_CON, GPIO_HIGH); + }else{ + gpio_set_value(SPK_CON, GPIO_LOW); + } +#endif + }else{ + codec_dai->capture.active = status; + } + } + return 0; } -#endif + #define WM8900_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\ SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) @@ -1131,11 +1159,9 @@ static struct snd_soc_dai_ops wm8900_dai_ops = { .set_pll = wm8900_set_dai_pll, .set_fmt = wm8900_set_dai_fmt, .digital_mute = wm8900_digital_mute, + .startup = wm8900_startup, + .trigger = wm8900_trigger, .shutdown = wm8900_shutdown, - .prepare = wm8900_prepare, -#ifdef CONFIG_MACH_RK29_MALATA - .trigger = wm8900_trigger, -#endif }; struct snd_soc_dai wm8900_dai = { @@ -1163,7 +1189,7 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec, { u16 reg; - WM8900_DBG("Enter:%s, %d, level=0x%08X \n", __FUNCTION__, __LINE__, level); + WM8900_DBG("Enter:%s, %d, level=0x%08X \n", __FUNCTION__, __LINE__, level); codec->bias_level = level; return 0; @@ -1270,11 +1296,6 @@ static int wm8900_suspend(struct platform_device *pdev, pm_message_t state) WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__); - //close SPK control GPIO - gpio_request(SPK_CON, NULL); - gpio_direction_output(SPK_CON,GPIO_LOW); - gpio_free(SPK_CON); - snd_soc_write(codec, WM8900_REG_RESET, 0); /* Stop the FLL in an orderly fashion */ @@ -1329,7 +1350,7 @@ static __devinit int wm8900_i2c_probe(struct i2c_client *i2c, unsigned int reg; int ret; - WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__); + WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__); wm8900 = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL); if (wm8900 == NULL) @@ -1404,7 +1425,7 @@ err: static __devexit int wm8900_i2c_remove(struct i2c_client *client) { - WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__); + WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__); snd_soc_unregister_dai(&wm8900_dai); snd_soc_unregister_codec(wm8900_codec); @@ -1418,10 +1439,16 @@ static __devexit int wm8900_i2c_remove(struct i2c_client *client) return 0; } +void wm8900_i2c_shutdown(struct i2c_client *client) +{ + WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__); + snd_soc_write(wm8900_codec, WM8900_REG_RESET, 0); +} + #ifdef CONFIG_PM static int wm8900_i2c_suspend(struct i2c_client *client, pm_message_t msg) { - WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__); + WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__); return snd_soc_suspend_device(&client->dev); } @@ -1449,6 +1476,7 @@ static struct i2c_driver wm8900_i2c_driver = { .remove = __devexit_p(wm8900_i2c_remove), .suspend = wm8900_i2c_suspend, .resume = wm8900_i2c_resume, + .shutdown = wm8900_i2c_shutdown, .id_table = wm8900_i2c_id, }; @@ -1458,16 +1486,14 @@ static int wm8900_probe(struct platform_device *pdev) struct snd_soc_codec *codec; int ret = 0; - WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__); + WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__); if (!wm8900_codec) { dev_err(&pdev->dev, "I2C client not yet instantiated\n"); return -ENODEV; } - -#ifdef CONFIG_MACH_RK29_MALATA - gpio_request(SPK_CON,"spk_con"); - gpio_set_value(SPK_CON, GPIO_LOW); +#if defined(SPK_CON) + gpio_request(SPK_CON,NULL); gpio_direction_output(SPK_CON, GPIO_LOW); #endif