From: 陈金泉 Date: Wed, 7 Aug 2013 03:31:20 +0000 (+0800) Subject: rk616 codec:sleep 150ms after setting spk/hp gpio and fix capture error X-Git-Tag: firefly_0821_release~6738 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=5f3340789d05507d50b2896e85760474377f5e41;p=firefly-linux-kernel-4.4.55.git rk616 codec:sleep 150ms after setting spk/hp gpio and fix capture error --- diff --git a/sound/soc/codecs/rk616_codec.c b/sound/soc/codecs/rk616_codec.c index ba44143344fc..9d307711894a 100755 --- a/sound/soc/codecs/rk616_codec.c +++ b/sound/soc/codecs/rk616_codec.c @@ -44,20 +44,14 @@ #define SPKOUT_VOLUME 22 //0~31 #define HPOUT_VOLUME 21 //0~31 -#ifdef CONFIG_MACH_RK_FAC -//for factorytool - int rk616_hdmi_ctrl=0; -#endif - - struct rk616_codec_priv { struct snd_soc_codec *codec; unsigned int stereo_sysclk; unsigned int rate; - int playback_active; - int capture_active; + bool is_playback_powerup; + bool is_capture_powerup; int spk_ctl_gpio; int hp_ctl_gpio; @@ -487,11 +481,12 @@ static int rk616_codec_write(struct snd_soc_codec *codec, unsigned int reg, unsi static int rk616_hw_write(const struct i2c_client *client, const char *buf, int count) { - struct snd_soc_codec *codec = rk616_priv->codec; + struct rk616_codec_priv *rk616 = rk616_priv; + struct snd_soc_codec *codec = rk616->codec; unsigned int reg, value; int ret = -1; - if (!rk616_priv || !rk616_priv->codec) { + if (!rk616 || !rk616->codec) { printk("%s : rk616_priv or rk616_priv->codec is NULL\n", __func__); return -EINVAL; } @@ -535,11 +530,12 @@ static int rk616_reset(struct snd_soc_codec *codec) int rk616_headset_mic_detect(bool headset_status) { + struct rk616_codec_priv *rk616 = rk616_priv; struct snd_soc_codec *codec = rk616_priv->codec; DBG("%s\n", __func__); - if (!rk616_priv || !rk616_priv->codec) { + if (!rk616 || !rk616->codec) { printk("%s : rk616_priv or rk616_priv->codec is NULL\n", __func__); return -EINVAL; } @@ -562,81 +558,19 @@ bool get_hdmi_state(void) { return is_hdmi_in; } + #ifdef CONFIG_MACH_RK_FAC void rk616_codec_set_spk(bool on) -{ - struct snd_soc_codec *codec = rk616_priv->codec; - - DBG("%s : %s\n", __func__, on ? "enable spk" : "disable spk"); - - if(rk616_hdmi_ctrl) - { - - if (!rk616_priv || !rk616_priv->codec) { - printk("%s : rk616_priv or rk616_priv->codec is NULL\n", __func__); - return; - } - - if (on) { - if (rk616_for_mid) - { - snd_soc_update_bits(codec, RK616_SPKL_CTL, - RK616_MUTE, 0); - snd_soc_update_bits(codec, RK616_SPKR_CTL, - RK616_MUTE, 0); - snd_soc_update_bits(codec, RK616_HPL_CTL, - RK616_MUTE, 0); - snd_soc_update_bits(codec, RK616_HPR_CTL, - RK616_MUTE, 0); - } - else - { - snd_soc_dapm_enable_pin(&codec->dapm, "Headphone Jack"); - snd_soc_dapm_enable_pin(&codec->dapm, "Ext Spk"); - } - } else { - if (rk616_priv->spk_ctl_gpio != INVALID_GPIO) { - DBG("%s : set spk ctl gpio LOW\n", __func__); - gpio_set_value(rk616_priv->spk_ctl_gpio, GPIO_LOW); - } - - if (rk616_priv->hp_ctl_gpio != INVALID_GPIO) { - DBG("%s : set hp ctl gpio LOW\n", __func__); - gpio_set_value(rk616_priv->hp_ctl_gpio, GPIO_LOW); - snd_soc_write(codec, RK616_CLK_CHPUMP, 0x41); - } - - if (rk616_for_mid) - { - snd_soc_update_bits(codec, RK616_SPKL_CTL, - RK616_MUTE, RK616_MUTE); - snd_soc_update_bits(codec, RK616_SPKR_CTL, - RK616_MUTE, RK616_MUTE); - snd_soc_update_bits(codec, RK616_HPL_CTL, - RK616_MUTE, RK616_MUTE); - snd_soc_update_bits(codec, RK616_HPR_CTL, - RK616_MUTE, RK616_MUTE); - } - else - { - snd_soc_dapm_disable_pin(&codec->dapm, "Headphone Jack"); - snd_soc_dapm_disable_pin(&codec->dapm, "Ext Spk"); - } - } - snd_soc_dapm_sync(&codec->dapm); - - is_hdmi_in = on ? 0 : 1; - } -} -EXPORT_SYMBOL_GPL(rk616_codec_set_spk); #else void codec_set_spk(bool on) +#endif { + struct rk616_codec_priv *rk616 = rk616_priv; struct snd_soc_codec *codec = rk616_priv->codec; DBG("%s : %s\n", __func__, on ? "enable spk" : "disable spk"); - if (!rk616_priv || !rk616_priv->codec) { + if (!rk616 || !rk616->codec) { printk("%s : rk616_priv or rk616_priv->codec is NULL\n", __func__); return; } @@ -659,14 +593,14 @@ void codec_set_spk(bool on) snd_soc_dapm_enable_pin(&codec->dapm, "Ext Spk"); } } else { - if (rk616_priv->spk_ctl_gpio != INVALID_GPIO) { + if (rk616->spk_ctl_gpio != INVALID_GPIO) { DBG("%s : set spk ctl gpio LOW\n", __func__); - gpio_set_value(rk616_priv->spk_ctl_gpio, GPIO_LOW); + gpio_set_value(rk616->spk_ctl_gpio, GPIO_LOW); } - if (rk616_priv->hp_ctl_gpio != INVALID_GPIO) { + if (rk616->hp_ctl_gpio != INVALID_GPIO) { DBG("%s : set hp ctl gpio LOW\n", __func__); - gpio_set_value(rk616_priv->hp_ctl_gpio, GPIO_LOW); + gpio_set_value(rk616->hp_ctl_gpio, GPIO_LOW); snd_soc_write(codec, RK616_CLK_CHPUMP, 0x41); } @@ -691,6 +625,9 @@ void codec_set_spk(bool on) is_hdmi_in = on ? 0 : 1; } +#ifdef CONFIG_MACH_RK_FAC +EXPORT_SYMBOL_GPL(rk616_codec_set_spk); +#else EXPORT_SYMBOL_GPL(codec_set_spk); #endif @@ -998,14 +935,16 @@ static const SOC_ENUM_SINGLE_DECL(rk616_voice_call_path_type, 0, 0, rk616_voice_ static int rk616_playback_path_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - if (!rk616_priv) { + struct rk616_codec_priv *rk616 = rk616_priv; + + if (!rk616) { printk("%s : rk616_priv is NULL\n", __func__); return -EINVAL; } DBG("%s : playback_path = %ld\n",__func__,ucontrol->value.integer.value[0]); - ucontrol->value.integer.value[0] = rk616_priv->playback_path; + ucontrol->value.integer.value[0] = rk616->playback_path; return 0; } @@ -1013,38 +952,39 @@ static int rk616_playback_path_get(struct snd_kcontrol *kcontrol, static int rk616_playback_path_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + struct rk616_codec_priv *rk616 = rk616_priv; struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - if (!rk616_priv) { + if (!rk616) { printk("%s : rk616_priv is NULL\n", __func__); return -EINVAL; } - if (rk616_priv->playback_path == ucontrol->value.integer.value[0]){ + if (rk616->playback_path == ucontrol->value.integer.value[0]){ DBG("%s : playback_path is not changed!\n",__func__); //return 0; } - rk616_priv->playback_path = ucontrol->value.integer.value[0]; + rk616->playback_path = ucontrol->value.integer.value[0]; printk("%s : set playback_path = %ld\n", __func__, - rk616_priv->playback_path); + rk616->playback_path); // mute output for pop noise - if (rk616_priv && rk616_priv->spk_ctl_gpio != INVALID_GPIO) { + if (rk616 && rk616->spk_ctl_gpio != INVALID_GPIO) { DBG("%s : set spk ctl gpio LOW\n", __func__); - gpio_set_value(rk616_priv->spk_ctl_gpio, GPIO_LOW); + gpio_set_value(rk616->spk_ctl_gpio, GPIO_LOW); } - if (rk616_priv && rk616_priv->hp_ctl_gpio != INVALID_GPIO) { + if (rk616 && rk616->hp_ctl_gpio != INVALID_GPIO) { DBG("%s : set hp ctl gpio LOW\n", __func__); - gpio_set_value(rk616_priv->hp_ctl_gpio, GPIO_LOW); + gpio_set_value(rk616->hp_ctl_gpio, GPIO_LOW); } if(get_hdmi_state()) return 0; - switch (rk616_priv->playback_path) { + switch (rk616->playback_path) { case OFF: break; case RCV: @@ -1069,9 +1009,11 @@ static int rk616_playback_path_put(struct snd_kcontrol *kcontrol, snd_soc_update_bits(codec, RK616_SPKR_CTL, RK616_VOL_MASK, SPKOUT_VOLUME); - if (rk616_priv && rk616_priv->spk_ctl_gpio != INVALID_GPIO) { + if (rk616 && rk616->spk_ctl_gpio != INVALID_GPIO) { DBG("%s : set spk ctl gpio HIGH\n", __func__); - gpio_set_value(rk616_priv->spk_ctl_gpio, GPIO_HIGH); + gpio_set_value(rk616->spk_ctl_gpio, GPIO_HIGH); + //sleep for MOSFET or SPK power amplifier chip + msleep(150); } break; case HP_PATH: @@ -1083,9 +1025,11 @@ static int rk616_playback_path_put(struct snd_kcontrol *kcontrol, snd_soc_update_bits(codec, RK616_SPKR_CTL, RK616_VOL_MASK, HPOUT_VOLUME); - if (rk616_priv && rk616_priv->hp_ctl_gpio != INVALID_GPIO) { + if (rk616 && rk616->hp_ctl_gpio != INVALID_GPIO) { DBG("%s : set hp ctl gpio HIGH\n", __func__); - gpio_set_value(rk616_priv->hp_ctl_gpio, GPIO_HIGH); + gpio_set_value(rk616->hp_ctl_gpio, GPIO_HIGH); + //sleep for MOSFET or SPK power amplifier chip + msleep(50); } break; case BT: @@ -1097,14 +1041,18 @@ static int rk616_playback_path_put(struct snd_kcontrol *kcontrol, snd_soc_update_bits(codec, RK616_SPKR_CTL, RK616_VOL_MASK, HPOUT_VOLUME); - if (rk616_priv && rk616_priv->spk_ctl_gpio != INVALID_GPIO) { + if (rk616 && rk616->spk_ctl_gpio != INVALID_GPIO) { DBG("%s : set spk ctl gpio HIGH\n", __func__); - gpio_set_value(rk616_priv->spk_ctl_gpio, GPIO_HIGH); + gpio_set_value(rk616->spk_ctl_gpio, GPIO_HIGH); + //sleep for MOSFET or SPK power amplifier chip + msleep(150); } - if (rk616_priv && rk616_priv->hp_ctl_gpio != INVALID_GPIO) { + if (rk616 && rk616->hp_ctl_gpio != INVALID_GPIO) { DBG("%s : set hp ctl gpio HIGH\n", __func__); - gpio_set_value(rk616_priv->hp_ctl_gpio, GPIO_HIGH); + gpio_set_value(rk616->hp_ctl_gpio, GPIO_HIGH); + //sleep for MOSFET or SPK power amplifier chip + msleep(50); } break; default: @@ -1117,7 +1065,9 @@ static int rk616_playback_path_put(struct snd_kcontrol *kcontrol, static int rk616_capture_path_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - if (!rk616_priv) { + struct rk616_codec_priv *rk616 = rk616_priv; + + if (!rk616) { printk("%s : rk616_priv is NULL\n", __func__); return -EINVAL; } @@ -1125,7 +1075,7 @@ static int rk616_capture_path_get(struct snd_kcontrol *kcontrol, DBG("%s : capture_path = %ld\n", __func__, ucontrol->value.integer.value[0]); - ucontrol->value.integer.value[0] = rk616_priv->capture_path; + ucontrol->value.integer.value[0] = rk616->capture_path; return 0; } @@ -1133,35 +1083,36 @@ static int rk616_capture_path_get(struct snd_kcontrol *kcontrol, static int rk616_capture_path_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + struct rk616_codec_priv *rk616 = rk616_priv; //struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - if (!rk616_priv) { + if (!rk616) { printk("%s : rk616_priv is NULL\n", __func__); return -EINVAL; } - if (rk616_priv->capture_path == ucontrol->value.integer.value[0]){ + if (rk616->capture_path == ucontrol->value.integer.value[0]){ DBG("%s : capture_path is not changed!\n", __func__); //return 0; } - rk616_priv->capture_path = ucontrol->value.integer.value[0]; + rk616->capture_path = ucontrol->value.integer.value[0]; - printk("%s : set capture_path = %ld\n", __func__, rk616_priv->capture_path); + printk("%s : set capture_path = %ld\n", __func__, rk616->capture_path); - switch (rk616_priv->capture_path) { + switch (rk616->capture_path) { case MIC_OFF: break; case Main_Mic: - if (rk616_priv && rk616_priv->mic_sel_gpio != INVALID_GPIO) { + if (rk616 && rk616->mic_sel_gpio != INVALID_GPIO) { DBG("%s : set mic sel gpio HIGH\n", __func__); - gpio_set_value(rk616_priv->mic_sel_gpio, GPIO_HIGH); + gpio_set_value(rk616->mic_sel_gpio, GPIO_HIGH); } break; case Hands_Free_Mic: - if (rk616_priv && rk616_priv->mic_sel_gpio != INVALID_GPIO) { + if (rk616 && rk616->mic_sel_gpio != INVALID_GPIO) { DBG("%s : set mic sel gpio HIGH\n", __func__); - gpio_set_value(rk616_priv->mic_sel_gpio, GPIO_LOW); + gpio_set_value(rk616->mic_sel_gpio, GPIO_LOW); } break; case BT_Sco_Mic: @@ -1176,7 +1127,9 @@ static int rk616_capture_path_put(struct snd_kcontrol *kcontrol, static int rk616_voice_call_path_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - if (!rk616_priv) { + struct rk616_codec_priv *rk616 = rk616_priv; + + if (!rk616) { printk("%s : rk616_priv is NULL\n", __func__); return -EINVAL; } @@ -1184,7 +1137,7 @@ static int rk616_voice_call_path_get(struct snd_kcontrol *kcontrol, DBG("%s : voice_call_path = %ld\n", __func__, ucontrol->value.integer.value[0]); - ucontrol->value.integer.value[0] = rk616_priv->voice_call_path; + ucontrol->value.integer.value[0] = rk616->voice_call_path; return 0; } @@ -1192,41 +1145,42 @@ static int rk616_voice_call_path_get(struct snd_kcontrol *kcontrol, static int rk616_voice_call_path_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + struct rk616_codec_priv *rk616 = rk616_priv; struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - if (!rk616_priv) { + if (!rk616) { printk("%s : rk616_priv is NULL\n", __func__); return -EINVAL; } - if (rk616_priv->voice_call_path == ucontrol->value.integer.value[0]){ + if (rk616->voice_call_path == ucontrol->value.integer.value[0]){ DBG("%s : voice_call_path is not changed!\n",__func__); //return 0; } - rk616_priv->voice_call_path = ucontrol->value.integer.value[0]; + rk616->voice_call_path = ucontrol->value.integer.value[0]; printk("%s : set voice_call_path = %ld\n", __func__, - rk616_priv->voice_call_path); + rk616->voice_call_path); - if (rk616_priv && rk616_priv->spk_ctl_gpio != INVALID_GPIO) { + if (rk616 && rk616->spk_ctl_gpio != INVALID_GPIO) { DBG("%s : set spk ctl gpio LOW\n", __func__); - gpio_set_value(rk616_priv->spk_ctl_gpio, GPIO_LOW); + gpio_set_value(rk616->spk_ctl_gpio, GPIO_LOW); } - if (rk616_priv && rk616_priv->hp_ctl_gpio != INVALID_GPIO) { + if (rk616 && rk616->hp_ctl_gpio != INVALID_GPIO) { DBG("%s : set hp ctl gpio LOW\n", __func__); - gpio_set_value(rk616_priv->hp_ctl_gpio, GPIO_LOW); + gpio_set_value(rk616->hp_ctl_gpio, GPIO_LOW); } - switch (rk616_priv->voice_call_path) { + switch (rk616->voice_call_path) { case OFF: break; case RCV: snd_soc_write(codec, RK616_MICBIAS_CTL, 0x7f); //open micbias 1 - if (rk616_priv && rk616_priv->mic_sel_gpio != INVALID_GPIO) { + if (rk616 && rk616->mic_sel_gpio != INVALID_GPIO) { DBG("%s : set mic sel gpio HIGH\n", __func__); - gpio_set_value(rk616_priv->mic_sel_gpio, GPIO_HIGH); + gpio_set_value(rk616->mic_sel_gpio, GPIO_HIGH); } //close incall route @@ -1244,16 +1198,18 @@ static int rk616_voice_call_path_put(struct snd_kcontrol *kcontrol, RK616_HML_F_PGAL | RK616_HMR_F_PGAL); // open spk for key tone - if (rk616_priv && rk616_priv->spk_ctl_gpio != INVALID_GPIO) { + if (rk616 && rk616->spk_ctl_gpio != INVALID_GPIO) { DBG("%s : set spk ctl gpio HIGH\n", __func__); - gpio_set_value(rk616_priv->spk_ctl_gpio, GPIO_HIGH); + gpio_set_value(rk616->spk_ctl_gpio, GPIO_HIGH); + //sleep for MOSFET or SPK power amplifier chip + msleep(150); } break; case SPK_PATH: snd_soc_write(codec, RK616_MICBIAS_CTL, 0x7f); //open micbias 1 - if (rk616_priv && rk616_priv->mic_sel_gpio != INVALID_GPIO) { + if (rk616 && rk616->mic_sel_gpio != INVALID_GPIO) { DBG("%s : set mic sel gpio HIGH\n", __func__); - gpio_set_value(rk616_priv->mic_sel_gpio, GPIO_HIGH); + gpio_set_value(rk616->mic_sel_gpio, GPIO_HIGH); } snd_soc_update_bits(codec, RK616_PGA_AGC_CTL, @@ -1272,17 +1228,19 @@ static int rk616_voice_call_path_put(struct snd_kcontrol *kcontrol, snd_soc_update_bits(codec, RK616_SPKR_CTL, RK616_VOL_MASK, SPKOUT_VOLUME); - if (rk616_priv && rk616_priv->spk_ctl_gpio != INVALID_GPIO) { + if (rk616 && rk616->spk_ctl_gpio != INVALID_GPIO) { DBG("%s : set spk ctl gpio HIGH\n", __func__); - gpio_set_value(rk616_priv->spk_ctl_gpio, GPIO_HIGH); + gpio_set_value(rk616->spk_ctl_gpio, GPIO_HIGH); + //sleep for MOSFET or SPK power amplifier chip + msleep(150); } break; case HP_PATH: case HP_NO_MIC: snd_soc_write(codec, RK616_MICBIAS_CTL, 0x7f); //open micbias 1 - if (rk616_priv && rk616_priv->mic_sel_gpio != INVALID_GPIO) { + if (rk616 && rk616->mic_sel_gpio != INVALID_GPIO) { DBG("%s : set mic sel gpio HIGH\n", __func__); - gpio_set_value(rk616_priv->mic_sel_gpio, GPIO_LOW); + gpio_set_value(rk616->mic_sel_gpio, GPIO_LOW); } snd_soc_update_bits(codec, RK616_PGA_AGC_CTL, @@ -1301,9 +1259,11 @@ static int rk616_voice_call_path_put(struct snd_kcontrol *kcontrol, snd_soc_update_bits(codec, RK616_SPKR_CTL, RK616_VOL_MASK, HPOUT_VOLUME); - if (rk616_priv && rk616_priv->hp_ctl_gpio != INVALID_GPIO) { + if (rk616 && rk616->hp_ctl_gpio != INVALID_GPIO) { DBG("%s : set hp ctl gpio HIGH\n", __func__); - gpio_set_value(rk616_priv->hp_ctl_gpio, GPIO_HIGH); + gpio_set_value(rk616->hp_ctl_gpio, GPIO_HIGH); + //sleep for MOSFET or SPK power amplifier chip + msleep(50); } break; case BT: @@ -1802,8 +1762,9 @@ static int rk616_set_dai_sysclk(struct snd_soc_dai *codec_dai, { struct rk616_codec_priv *rk616 = rk616_priv; - if (!rk616) { - printk("%s : rk616 is NULL\n", __func__); + if (!rk616 || !rk616_mfd) { + printk("%s : %s %s\n", __func__, !rk616 ? "rk616 is NULL" : "", + !rk616_mfd ? "rk616_mfd is NULL" : ""); return -EINVAL; } @@ -2037,6 +1998,7 @@ static int rk616_hw_params(struct snd_pcm_substream *substream, static int rk616_digital_mute(struct snd_soc_dai *dai, int mute) { + struct rk616_codec_priv *rk616 = rk616_priv; struct snd_soc_codec *codec = dai->codec; unsigned int is_spk_pd, is_hp_pd; @@ -2046,6 +2008,11 @@ static int rk616_digital_mute(struct snd_soc_dai *dai, int mute) return 0; } + if (!rk616) { + printk("%s : rk616_priv is NULL\n", __func__); + return -EINVAL; + } + is_spk_pd = RK616_PWRD & snd_soc_read(codec, RK616_SPKL_CTL); is_spk_pd &= RK616_PWRD & snd_soc_read(codec, RK616_SPKR_CTL); @@ -2053,32 +2020,39 @@ static int rk616_digital_mute(struct snd_soc_dai *dai, int mute) is_hp_pd &= RK616_PWRD & snd_soc_read(codec, RK616_HPR_CTL); if (mute) { - if (rk616_priv && rk616_priv->spk_ctl_gpio != INVALID_GPIO && + if (rk616 && rk616->spk_ctl_gpio != INVALID_GPIO && !is_spk_pd) { DBG("%s : set spk ctl gpio LOW\n", __func__); - gpio_set_value(rk616_priv->spk_ctl_gpio, GPIO_LOW); + gpio_set_value(rk616->spk_ctl_gpio, GPIO_LOW); } - if (rk616_priv && rk616_priv->hp_ctl_gpio != INVALID_GPIO && + if (rk616 && rk616->hp_ctl_gpio != INVALID_GPIO && !is_hp_pd) { DBG("%s : set hp ctl gpio LOW\n", __func__); - gpio_set_value(rk616_priv->hp_ctl_gpio, GPIO_LOW); + gpio_set_value(rk616->hp_ctl_gpio, GPIO_LOW); snd_soc_write(codec, RK616_CLK_CHPUMP, 0x41); } } else { - if (rk616_priv && rk616_priv->hp_ctl_gpio != INVALID_GPIO && + if (rk616 && rk616->hp_ctl_gpio != INVALID_GPIO && !is_hp_pd) { snd_soc_write(codec, RK616_CLK_CHPUMP, 0x21); msleep(10); DBG("%s : set hp ctl gpio HIGH\n", __func__); - gpio_set_value(rk616_priv->hp_ctl_gpio, GPIO_HIGH); + gpio_set_value(rk616->hp_ctl_gpio, GPIO_HIGH); } - if (rk616_priv && rk616_priv->spk_ctl_gpio != INVALID_GPIO && + if (rk616 && rk616->spk_ctl_gpio != INVALID_GPIO && !is_spk_pd) { DBG("%s : set spk ctl gpio HIGH\n", __func__); - gpio_set_value(rk616_priv->spk_ctl_gpio, GPIO_HIGH); + gpio_set_value(rk616->spk_ctl_gpio, GPIO_HIGH); } + + //sleep for MOSFET or SPK power amplifier chip + if (rk616 && rk616->spk_ctl_gpio != INVALID_GPIO && + !is_spk_pd) + msleep(150); + else + msleep(50); } return 0; @@ -2161,10 +2135,11 @@ static struct rk616_reg_val_typ capture_power_down_list[] = { static int rk616_codec_power_up(int type) { - struct snd_soc_codec *codec = rk616_priv->codec; + struct rk616_codec_priv *rk616 = rk616_priv; + struct snd_soc_codec *codec = rk616->codec; int i; - if (!rk616_priv || !rk616_priv->codec) { + if (!rk616 || !rk616->codec) { printk("%s : rk616_priv or rk616_priv->codec is NULL\n", __func__); return -EINVAL; } @@ -2175,14 +2150,14 @@ static int rk616_codec_power_up(int type) if (type == RK616_CODEC_PLAYBACK) { // mute output for pop noise - if (rk616_priv && rk616_priv->spk_ctl_gpio != INVALID_GPIO) { + if (rk616 && rk616->spk_ctl_gpio != INVALID_GPIO) { DBG("%s : set spk ctl gpio LOW\n", __func__); - gpio_set_value(rk616_priv->spk_ctl_gpio, GPIO_LOW); + gpio_set_value(rk616->spk_ctl_gpio, GPIO_LOW); } - if (rk616_priv && rk616_priv->hp_ctl_gpio != INVALID_GPIO) { + if (rk616 && rk616->hp_ctl_gpio != INVALID_GPIO) { DBG("%s : set hp ctl gpio LOW\n", __func__); - gpio_set_value(rk616_priv->hp_ctl_gpio, GPIO_LOW); + gpio_set_value(rk616->hp_ctl_gpio, GPIO_LOW); } for (i = 0; i < RK616_CODEC_PLAYBACK_POWER_UP_LIST_LEN; i++) { @@ -2194,11 +2169,13 @@ static int rk616_codec_power_up(int type) #else codec_set_spk(!get_hdmi_state()); #endif + rk616->is_playback_powerup = true; } else if (type == RK616_CODEC_CAPTURE) { for (i = 0; i < RK616_CODEC_CAPTURE_POWER_UP_LIST_LEN; i++) { snd_soc_write(codec, capture_power_up_list[i].reg, capture_power_up_list[i].value); } + rk616->is_capture_powerup = true; } return 0; @@ -2207,15 +2184,16 @@ static int rk616_codec_power_up(int type) static int rk616_codec_power_down(int type) { struct rk616_codec_priv *rk616 = rk616_priv; - struct snd_soc_codec *codec = rk616_priv->codec; + struct snd_soc_codec *codec = rk616->codec; int i; - if (!rk616_priv || !rk616_priv->codec) { + if (!rk616 || !rk616->codec) { printk("%s : rk616_priv or rk616_priv->codec is NULL\n", __func__); return -EINVAL; } - if (rk616->playback_active <= 0 && rk616->capture_active <= 0) + if ((type == RK616_CODEC_PLAYBACK && !(rk616->is_capture_powerup)) || + (type == RK616_CODEC_CAPTURE && !(rk616->is_playback_powerup))) type = RK616_CODEC_ALL; printk("%s : power down %s%s%s\n", __func__, @@ -2226,14 +2204,14 @@ static int rk616_codec_power_down(int type) // mute output for pop noise if (type == RK616_CODEC_PLAYBACK || type == RK616_CODEC_ALL) { - if (rk616_priv && rk616_priv->spk_ctl_gpio != INVALID_GPIO) { + if (rk616 && rk616->spk_ctl_gpio != INVALID_GPIO) { DBG("%s : set spk ctl gpio LOW\n", __func__); - gpio_set_value(rk616_priv->spk_ctl_gpio, GPIO_LOW); + gpio_set_value(rk616->spk_ctl_gpio, GPIO_LOW); } - if (rk616_priv && rk616_priv->hp_ctl_gpio != INVALID_GPIO) { + if (rk616 && rk616->hp_ctl_gpio != INVALID_GPIO) { DBG("%s : set hp ctl gpio LOW\n", __func__); - gpio_set_value(rk616_priv->hp_ctl_gpio, GPIO_LOW); + gpio_set_value(rk616->hp_ctl_gpio, GPIO_LOW); } } @@ -2242,13 +2220,17 @@ static int rk616_codec_power_down(int type) snd_soc_write(codec, capture_power_down_list[i].reg, capture_power_down_list[i].value); } + rk616->is_capture_powerup = false; } else if (type == RK616_CODEC_PLAYBACK) { for (i = 0; i < RK616_CODEC_PLAYBACK_POWER_DOWN_LIST_LEN; i++) { snd_soc_write(codec, playback_power_down_list[i].reg, playback_power_down_list[i].value); } + rk616->is_playback_powerup = false; } else if (type == RK616_CODEC_ALL) { rk616_reset(codec); + rk616->is_playback_powerup = false; + rk616->is_capture_powerup = false; } return 0; @@ -2275,8 +2257,6 @@ static int rk616_startup(struct snd_pcm_substream *substream, { struct rk616_codec_priv *rk616 = rk616_priv; bool playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); - bool is_codec_playback_running = rk616->playback_active > 0 ; - bool is_codec_capture_running = rk616->capture_active > 0; if (!rk616_for_mid) { @@ -2293,22 +2273,14 @@ static int rk616_startup(struct snd_pcm_substream *substream, playback ? "PLAYBACK":"CAPTURE"); if (playback) { - rk616->playback_active++; - - if (rk616->playback_active > 0 && !is_codec_playback_running) { + if (!rk616->is_playback_powerup) rk616_codec_power_up(RK616_CODEC_PLAYBACK); - } } else {//capture - rk616->capture_active++; - if (rk616->capture_active > 0 && !is_codec_capture_running) { - cancel_delayed_work_sync(&capture_delayed_work); - if (rk616_codec_work_capture_type == RK616_CODEC_WORK_NULL) { - rk616_codec_power_up(RK616_CODEC_CAPTURE); - } else { - DBG("Capture is being closed, so interrupt work process ! \n"); - rk616_codec_work_capture_type = RK616_CODEC_WORK_NULL; - } - } + cancel_delayed_work_sync(&capture_delayed_work); + rk616_codec_work_capture_type = RK616_CODEC_WORK_NULL; + + if (!rk616->is_capture_powerup) + rk616_codec_power_up(RK616_CODEC_CAPTURE); } return 0; @@ -2319,9 +2291,7 @@ static void rk616_shutdown(struct snd_pcm_substream *substream, { struct rk616_codec_priv *rk616 = rk616_priv; bool playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); - bool is_codec_playback_running = rk616->playback_active > 0; - bool is_codec_capture_running = rk616->capture_active > 0; - + if (!rk616_for_mid) { DBG("%s immediately return for phone\n", __func__); @@ -2337,29 +2307,18 @@ static void rk616_shutdown(struct snd_pcm_substream *substream, playback ? "PLAYBACK":"CAPTURE"); if (playback) { - rk616->playback_active--; - - if (rk616->playback_active <= 0) { - if (is_codec_playback_running == true) + if (dai->playback_active <= 0) { + if (rk616->is_playback_powerup) rk616_codec_power_down(RK616_CODEC_PLAYBACK); else DBG("Playback has been closed, so return !\n"); } } else {//capture - rk616->capture_active--; - - if (rk616->capture_active <= 0) { + if (dai->capture_active <= 0) { if ((rk616_codec_work_capture_type != RK616_CODEC_WORK_POWER_DOWN) && - (is_codec_capture_running == true)) { + rk616->is_capture_powerup) { cancel_delayed_work_sync(&capture_delayed_work); - /* - * If rk616_codec_work_capture_type is NULL means codec already power down, - * so power up codec. - * If rk616_codec_work_capture_type is RK616_CODEC_WORK_POWER_UP it means - * codec haven't be powered up, so we don't need to power down codec. - * If it is playback call power down, power down immediatly, because audioflinger - * already has delay 3s. - */ + rk616_codec_work_capture_type = RK616_CODEC_WORK_POWER_DOWN; queue_delayed_work(rk616_codec_workq, &capture_delayed_work,msecs_to_jiffies(3000)); } else { @@ -2500,8 +2459,8 @@ static int rk616_probe(struct snd_soc_codec *codec) if (rk616_for_mid) { - rk616->playback_active = 0; - rk616->capture_active = 0; + rk616->is_playback_powerup = false; + rk616->is_capture_powerup = false; rk616_codec_workq = create_freezable_workqueue("rk616-codec"); @@ -2557,10 +2516,6 @@ static int rk616_probe(struct snd_soc_codec *codec) ARRAY_SIZE(rk616_dapm_routes)); } - - #ifdef CONFIG_MACH_RK_FAC - rk616_hdmi_ctrl=1; - #endif return 0; @@ -2575,18 +2530,20 @@ err__: /* power down chip */ static int rk616_remove(struct snd_soc_codec *codec) { + struct rk616_codec_priv *rk616 = rk616_priv; + DBG("%s\n", __func__); - if (!rk616_priv) { + if (!rk616) { printk("%s : rk616_priv is NULL\n", __func__); return 0; } - if (rk616_priv->spk_ctl_gpio != INVALID_GPIO) - gpio_set_value(rk616_priv->spk_ctl_gpio, GPIO_LOW); + if (rk616->spk_ctl_gpio != INVALID_GPIO) + gpio_set_value(rk616->spk_ctl_gpio, GPIO_LOW); - if (rk616_priv->hp_ctl_gpio != INVALID_GPIO) - gpio_set_value(rk616_priv->hp_ctl_gpio, GPIO_LOW); + if (rk616->hp_ctl_gpio != INVALID_GPIO) + gpio_set_value(rk616->hp_ctl_gpio, GPIO_LOW); mdelay(10); @@ -2604,8 +2561,8 @@ static int rk616_remove(struct snd_soc_codec *codec) snd_soc_write(codec, RK616_RESET, 0x3); mdelay(10); - if (rk616_priv) - kfree(rk616_priv); + if (rk616) + kfree(rk616); return 0; } @@ -2648,18 +2605,21 @@ static __devexit int rk616_platform_remove(struct platform_device *pdev) void rk616_platform_shutdown(struct platform_device *pdev) { + struct rk616_codec_priv *rk616 = rk616_priv; + struct snd_soc_codec *codec = rk616->codec; + DBG("%s\n", __func__); - if (!rk616_priv || !rk616_priv->codec) { + if (!rk616 || !rk616->codec) { printk("%s : rk616_priv or rk616_priv->codec is NULL\n", __func__); return; } - if (rk616_priv->spk_ctl_gpio != INVALID_GPIO) - gpio_set_value(rk616_priv->spk_ctl_gpio, GPIO_LOW); + if (rk616->spk_ctl_gpio != INVALID_GPIO) + gpio_set_value(rk616->spk_ctl_gpio, GPIO_LOW); - if (rk616_priv->hp_ctl_gpio != INVALID_GPIO) - gpio_set_value(rk616_priv->hp_ctl_gpio, GPIO_LOW); + if (rk616->hp_ctl_gpio != INVALID_GPIO) + gpio_set_value(rk616->hp_ctl_gpio, GPIO_LOW); mdelay(10); @@ -2671,12 +2631,12 @@ void rk616_platform_shutdown(struct platform_device *pdev) } } - snd_soc_write(rk616_priv->codec, RK616_RESET, 0xfc); + snd_soc_write(codec, RK616_RESET, 0xfc); mdelay(10); - snd_soc_write(rk616_priv->codec, RK616_RESET, 0x3); + snd_soc_write(codec, RK616_RESET, 0x3); - if (rk616_priv) - kfree(rk616_priv); + if (rk616) + kfree(rk616); } static struct platform_driver rk616_codec_driver = {