Loading sound/soc/codecs/msm8x16-wcd.c +77 −0 Original line number Diff line number Diff line Loading @@ -3131,6 +3131,80 @@ static int msm8x16_wcd_codec_remove(struct snd_soc_codec *codec) return 0; } int msm8x16_wcd_suspend(struct snd_soc_codec *codec) { struct msm8916_asoc_mach_data *pdata = NULL; pdata = snd_soc_card_get_drvdata(codec->card); pr_debug("%s: mclk cnt = %d, dis_work_mclk = %d\n", __func__, atomic_read(&pdata->mclk_rsc_ref), atomic_read(&pdata->dis_work_mclk)); pr_debug("%s: mclk_act = %d\n", __func__, atomic_read(&pdata->mclk_act)); mutex_lock(&pdata->cdc_mclk_mutex); if ((atomic_read(&pdata->dis_work_mclk) == true) || (atomic_read(&pdata->mclk_rsc_ref) > 0)) { pdata->digital_cdc_clk.clk_val = 0; afe_set_digital_codec_core_clock( AFE_PORT_ID_PRIMARY_MI2S_RX, &pdata->digital_cdc_clk); /* * set mclk activity to resource as * it will get updated accordingly going further in this * function. */ atomic_set(&pdata->mclk_act, MCLK_SUS_RSC); if (atomic_read(&pdata->dis_work_mclk) == true) { cancel_delayed_work_sync( &pdata->enable_mclk_work); atomic_set(&pdata->mclk_act, MCLK_SUS_DIS); atomic_set(&pdata->dis_work_mclk, false); } } else /* * mark no activity on mclk in this suspend */ atomic_set(&pdata->mclk_act, MCLK_SUS_NO_ACT); mutex_unlock(&pdata->cdc_mclk_mutex); return 0; } int msm8x16_wcd_resume(struct snd_soc_codec *codec) { struct msm8916_asoc_mach_data *pdata = NULL; pdata = snd_soc_card_get_drvdata(codec->card); pr_debug("%s: mclk cnt = %d, dis_work_mclk = %d\n", __func__, atomic_read(&pdata->mclk_rsc_ref), atomic_read(&pdata->dis_work_mclk)); pr_debug("%s: mclk_act = %d\n", __func__, atomic_read(&pdata->mclk_act)); if (atomic_read(&pdata->mclk_act) == MCLK_SUS_NO_ACT) /* * no activity in suspend just return */ return 0; mutex_lock(&pdata->cdc_mclk_mutex); if ((atomic_read(&pdata->dis_work_mclk) == false) || (atomic_read(&pdata->mclk_rsc_ref) > 0)) { pdata->digital_cdc_clk.clk_val = pdata->mclk_freq; afe_set_digital_codec_core_clock( AFE_PORT_ID_PRIMARY_MI2S_RX, &pdata->digital_cdc_clk); if (atomic_read(&pdata->mclk_act) == MCLK_SUS_DIS) { /* * MCLK activity marked as the disabled during suspend * this indicated MCLK was enabled to read and write the * AHB bus. */ atomic_set(&pdata->dis_work_mclk, true); schedule_delayed_work(&pdata->enable_mclk_work, 50); } } mutex_unlock(&pdata->cdc_mclk_mutex); return 0; } static struct snd_soc_codec_driver soc_codec_dev_msm8x16_wcd = { .probe = msm8x16_wcd_codec_probe, .remove = msm8x16_wcd_codec_remove, Loading @@ -3138,6 +3212,9 @@ static struct snd_soc_codec_driver soc_codec_dev_msm8x16_wcd = { .read = msm8x16_wcd_read, .write = msm8x16_wcd_write, .suspend = msm8x16_wcd_suspend, .resume = msm8x16_wcd_resume, .readable_register = msm8x16_wcd_readable, .volatile_register = msm8x16_wcd_volatile, Loading sound/soc/codecs/msm8x16-wcd.h +8 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,13 @@ (((reg >= 0x200) && (reg <= 0x4FF)) ? 1 : 0) #define MSM8X16_WCD_IS_TOMBAK_REG(reg) \ (((reg >= 0x000) && (reg <= 0x1FF)) ? 1 : 0) /* * MCLK activity indicators during suspend and resume call */ #define MCLK_SUS_DIS 1 #define MCLK_SUS_RSC 2 #define MCLK_SUS_NO_ACT 3 extern const u8 msm8x16_wcd_reg_readable[MSM8X16_WCD_CACHE_SIZE]; extern const u8 msm8x16_wcd_reg_readonly[MSM8X16_WCD_CACHE_SIZE]; extern const u8 msm8x16_wcd_reset_reg_defaults[MSM8X16_WCD_CACHE_SIZE]; Loading Loading @@ -124,6 +131,7 @@ struct msm8916_asoc_mach_data { int mclk_freq; atomic_t mclk_rsc_ref; atomic_t dis_work_mclk; atomic_t mclk_act; struct mutex cdc_mclk_mutex; struct delayed_work enable_mclk_work; struct afe_digital_clk_cfg digital_cdc_clk; Loading sound/soc/msm/msm8x16.c +1 −1 Original line number Diff line number Diff line Loading @@ -580,6 +580,7 @@ static int msm8x16_enable_codec_ext_clk(struct snd_soc_codec *codec, msm8x16_wcd_mclk_enable(codec, 1, dapm); } } else { msm8x16_wcd_mclk_enable(codec, 0, dapm); mutex_lock(&pdata->cdc_mclk_mutex); atomic_set(&pdata->mclk_rsc_ref, 0); cancel_delayed_work_sync(&pdata->enable_mclk_work); Loading @@ -589,7 +590,6 @@ static int msm8x16_enable_codec_ext_clk(struct snd_soc_codec *codec, &pdata->digital_cdc_clk); atomic_set(&pdata->dis_work_mclk, false); mutex_unlock(&pdata->cdc_mclk_mutex); msm8x16_wcd_mclk_enable(codec, 0, dapm); } return ret; } Loading Loading
sound/soc/codecs/msm8x16-wcd.c +77 −0 Original line number Diff line number Diff line Loading @@ -3131,6 +3131,80 @@ static int msm8x16_wcd_codec_remove(struct snd_soc_codec *codec) return 0; } int msm8x16_wcd_suspend(struct snd_soc_codec *codec) { struct msm8916_asoc_mach_data *pdata = NULL; pdata = snd_soc_card_get_drvdata(codec->card); pr_debug("%s: mclk cnt = %d, dis_work_mclk = %d\n", __func__, atomic_read(&pdata->mclk_rsc_ref), atomic_read(&pdata->dis_work_mclk)); pr_debug("%s: mclk_act = %d\n", __func__, atomic_read(&pdata->mclk_act)); mutex_lock(&pdata->cdc_mclk_mutex); if ((atomic_read(&pdata->dis_work_mclk) == true) || (atomic_read(&pdata->mclk_rsc_ref) > 0)) { pdata->digital_cdc_clk.clk_val = 0; afe_set_digital_codec_core_clock( AFE_PORT_ID_PRIMARY_MI2S_RX, &pdata->digital_cdc_clk); /* * set mclk activity to resource as * it will get updated accordingly going further in this * function. */ atomic_set(&pdata->mclk_act, MCLK_SUS_RSC); if (atomic_read(&pdata->dis_work_mclk) == true) { cancel_delayed_work_sync( &pdata->enable_mclk_work); atomic_set(&pdata->mclk_act, MCLK_SUS_DIS); atomic_set(&pdata->dis_work_mclk, false); } } else /* * mark no activity on mclk in this suspend */ atomic_set(&pdata->mclk_act, MCLK_SUS_NO_ACT); mutex_unlock(&pdata->cdc_mclk_mutex); return 0; } int msm8x16_wcd_resume(struct snd_soc_codec *codec) { struct msm8916_asoc_mach_data *pdata = NULL; pdata = snd_soc_card_get_drvdata(codec->card); pr_debug("%s: mclk cnt = %d, dis_work_mclk = %d\n", __func__, atomic_read(&pdata->mclk_rsc_ref), atomic_read(&pdata->dis_work_mclk)); pr_debug("%s: mclk_act = %d\n", __func__, atomic_read(&pdata->mclk_act)); if (atomic_read(&pdata->mclk_act) == MCLK_SUS_NO_ACT) /* * no activity in suspend just return */ return 0; mutex_lock(&pdata->cdc_mclk_mutex); if ((atomic_read(&pdata->dis_work_mclk) == false) || (atomic_read(&pdata->mclk_rsc_ref) > 0)) { pdata->digital_cdc_clk.clk_val = pdata->mclk_freq; afe_set_digital_codec_core_clock( AFE_PORT_ID_PRIMARY_MI2S_RX, &pdata->digital_cdc_clk); if (atomic_read(&pdata->mclk_act) == MCLK_SUS_DIS) { /* * MCLK activity marked as the disabled during suspend * this indicated MCLK was enabled to read and write the * AHB bus. */ atomic_set(&pdata->dis_work_mclk, true); schedule_delayed_work(&pdata->enable_mclk_work, 50); } } mutex_unlock(&pdata->cdc_mclk_mutex); return 0; } static struct snd_soc_codec_driver soc_codec_dev_msm8x16_wcd = { .probe = msm8x16_wcd_codec_probe, .remove = msm8x16_wcd_codec_remove, Loading @@ -3138,6 +3212,9 @@ static struct snd_soc_codec_driver soc_codec_dev_msm8x16_wcd = { .read = msm8x16_wcd_read, .write = msm8x16_wcd_write, .suspend = msm8x16_wcd_suspend, .resume = msm8x16_wcd_resume, .readable_register = msm8x16_wcd_readable, .volatile_register = msm8x16_wcd_volatile, Loading
sound/soc/codecs/msm8x16-wcd.h +8 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,13 @@ (((reg >= 0x200) && (reg <= 0x4FF)) ? 1 : 0) #define MSM8X16_WCD_IS_TOMBAK_REG(reg) \ (((reg >= 0x000) && (reg <= 0x1FF)) ? 1 : 0) /* * MCLK activity indicators during suspend and resume call */ #define MCLK_SUS_DIS 1 #define MCLK_SUS_RSC 2 #define MCLK_SUS_NO_ACT 3 extern const u8 msm8x16_wcd_reg_readable[MSM8X16_WCD_CACHE_SIZE]; extern const u8 msm8x16_wcd_reg_readonly[MSM8X16_WCD_CACHE_SIZE]; extern const u8 msm8x16_wcd_reset_reg_defaults[MSM8X16_WCD_CACHE_SIZE]; Loading Loading @@ -124,6 +131,7 @@ struct msm8916_asoc_mach_data { int mclk_freq; atomic_t mclk_rsc_ref; atomic_t dis_work_mclk; atomic_t mclk_act; struct mutex cdc_mclk_mutex; struct delayed_work enable_mclk_work; struct afe_digital_clk_cfg digital_cdc_clk; Loading
sound/soc/msm/msm8x16.c +1 −1 Original line number Diff line number Diff line Loading @@ -580,6 +580,7 @@ static int msm8x16_enable_codec_ext_clk(struct snd_soc_codec *codec, msm8x16_wcd_mclk_enable(codec, 1, dapm); } } else { msm8x16_wcd_mclk_enable(codec, 0, dapm); mutex_lock(&pdata->cdc_mclk_mutex); atomic_set(&pdata->mclk_rsc_ref, 0); cancel_delayed_work_sync(&pdata->enable_mclk_work); Loading @@ -589,7 +590,6 @@ static int msm8x16_enable_codec_ext_clk(struct snd_soc_codec *codec, &pdata->digital_cdc_clk); atomic_set(&pdata->dis_work_mclk, false); mutex_unlock(&pdata->cdc_mclk_mutex); msm8x16_wcd_mclk_enable(codec, 0, dapm); } return ret; } Loading