rk616 codec:Do not change mclk when HDMI is in and correct format

This commit is contained in:
陈金泉
2013-05-31 09:22:28 +08:00
parent 95a95292dc
commit 0a72b74008
2 changed files with 117 additions and 121 deletions

View File

@@ -151,44 +151,27 @@ static const unsigned int rk616_reg_defaults[RK616_PGAR_AGC_CTL5 + 1] = {
[RK616_PGAR_AGC_CTL5] = 0x0038,
};
/* mfd registers default list */
static struct rk616_reg_val_typ rk616_mfd_reg_defaults[] = {
{CRU_CODEC_DIV, 0x00000000},
{CRU_IO_CON0, (I2S1_OUT_DISABLE | I2S0_OUT_DISABLE | I2S1_PD_DISABLE | I2S0_PD_DISABLE) |
((I2S1_OUT_DISABLE | I2S0_OUT_DISABLE | I2S1_PD_DISABLE | I2S0_PD_DISABLE) << 16)},
{CRU_IO_CON1, (I2S1_SI_EN | I2S0_SI_EN) | ((I2S1_SI_EN | I2S0_SI_EN) << 16)},
{CRU_PCM2IS2_CON2, (0) | ((APS_SEL | APS_CLR | I2S_CHANNEL_SEL) << 16)},
{CRU_PCM2IS2_CON2, (0) | ((PCM_TO_I2S_MUX | APS_SEL | APS_CLR | I2S_CHANNEL_SEL) << 16)},
{CRU_CFGMISC_CON, 0x00000000},
};
static struct rk616_reg_val_typ rk616_mfd_codec_bit_list[] = {
{CRU_CFGMISC_CON, AD_DA_LOOP | MICDET2_PIN_F_CODEC | MICDET1_PIN_F_CODEC},
};
#define RK616_MFD_CODEC_BIT_LEN ARRAY_SIZE(rk616_mfd_codec_bit_list)
/* mfd registers cache list */
static struct rk616_reg_val_typ rk616_mfd_reg_cache[] = {
{CRU_CODEC_DIV, 0x00000000},
{CRU_IO_CON0, (I2S1_OUT_DISABLE | I2S0_OUT_DISABLE | I2S1_PD_DISABLE | I2S0_PD_DISABLE) |
((I2S1_OUT_DISABLE | I2S0_OUT_DISABLE | I2S1_PD_DISABLE | I2S0_PD_DISABLE) << 16)},
{CRU_IO_CON1, (I2S1_SI_EN | I2S0_SI_EN) | ((I2S1_SI_EN | I2S0_SI_EN) << 16)},
{CRU_PCM2IS2_CON2, (0) | ((APS_SEL | APS_CLR | I2S_CHANNEL_SEL) << 16)},
{CRU_PCM2IS2_CON2, (0) | ((PCM_TO_I2S_MUX | APS_SEL | APS_CLR | I2S_CHANNEL_SEL) << 16)},
{CRU_CFGMISC_CON, 0x00000000},
};
#define RK616_MFD_REG_LEN ARRAY_SIZE(rk616_mfd_reg_cache)
static int rk616_mfd_codec_bit(unsigned int reg)
{
int i;
for (i = 0; i < RK616_MFD_CODEC_BIT_LEN; i++) {
if (rk616_mfd_codec_bit_list[i].reg == reg)
return i;
}
return -1;
}
static int rk616_mfd_register(unsigned int reg)
{
int i;
@@ -201,6 +184,7 @@ static int rk616_mfd_register(unsigned int reg)
return 0;
}
/* If register's bit16-31 is mask bit add to this fun */
static int rk616_mfd_mask_register(unsigned int reg)
{
switch (reg) {
@@ -213,6 +197,23 @@ static int rk616_mfd_mask_register(unsigned int reg)
}
}
static struct rk616_reg_val_typ rk616_mfd_codec_bit_list[] = {
{CRU_CFGMISC_CON, AD_DA_LOOP | MICDET2_PIN_F_CODEC | MICDET1_PIN_F_CODEC},
};
#define RK616_MFD_CODEC_BIT_LEN ARRAY_SIZE(rk616_mfd_codec_bit_list)
static int rk616_mfd_codec_bit(unsigned int reg)
{
int i;
for (i = 0; i < RK616_MFD_CODEC_BIT_LEN; i++) {
if (rk616_mfd_codec_bit_list[i].reg == reg)
return i;
}
return -1;
}
static struct rk616_init_bit_typ rk616_init_bit_list[] = {
{RK616_SPKL_CTL, RK616_MUTE, RK616_INIT_MASK},
{RK616_SPKR_CTL, RK616_MUTE, RK616_INIT_MASK},
@@ -468,8 +469,7 @@ static int rk616_hw_write(const struct i2c_client *client, const char *buf, int
int ret = -1;
if (!rk616_priv || !rk616_priv->codec) {
printk("%s : %s %s\n", __func__, rk616_priv ? "" : "rk616_priv is NULL",
rk616_priv->codec ? "" : "rk616_priv->codec is NULL");
printk("%s : rk616_priv or rk616_priv->codec is NULL\n", __func__);
return -EINVAL;
}
@@ -494,7 +494,8 @@ static int rk616_reset(struct snd_soc_codec *codec)
mdelay(10);
for (i = 0; i < RK616_MFD_REG_LEN; i++)
snd_soc_write(codec, rk616_mfd_reg_defaults[i].reg, rk616_mfd_reg_defaults[i].value);
snd_soc_write(codec, rk616_mfd_reg_defaults[i].reg,
rk616_mfd_reg_defaults[i].value);
memcpy(codec->reg_cache, rk616_reg_defaults,
sizeof(rk616_reg_defaults));
@@ -516,8 +517,7 @@ int rk616_headset_mic_detect(bool headset_status)
DBG("%s\n", __func__);
if (!rk616_priv || !rk616_priv->codec) {
printk("%s : %s %s\n", __func__, rk616_priv ? "" : "rk616_priv is NULL",
rk616_priv->codec ? "" : "rk616_priv->codec is NULL");
printk("%s : rk616_priv or rk616_priv->codec is NULL\n", __func__);
return -EINVAL;
}
@@ -547,8 +547,7 @@ void codec_set_spk(bool on)
DBG("%s : %s\n", __func__, on ? "enable spk" : "disable spk");
if (!rk616_priv || !rk616_priv->codec) {
printk("%s : %s %s\n", __func__, rk616_priv ? "" : "rk616_priv is NULL",
rk616_priv->codec ? "" : "rk616_priv->codec is NULL");
printk("%s : rk616_priv or rk616_priv->codec is NULL\n", __func__);
return;
}
@@ -1018,11 +1017,11 @@ static const struct snd_kcontrol_new rk616_mixinl[] = {
static const struct snd_kcontrol_new rk616_mixinr[] = {
SOC_DAPM_SINGLE("MIC2N Switch", RK616_MIXINR_CTL,
RK616_MIR_F_MIC2N_SFT, 1, 1),
SOC_DAPM_SINGLE("IN1P Switch", RK616_MIXINL_CTL,
SOC_DAPM_SINGLE("IN1P Switch", RK616_MIXINR_CTL,
RK616_MIR_F_IN1P_SFT, 1, 1),
SOC_DAPM_SINGLE("IN3R Switch", RK616_MIXINL_CTL,
SOC_DAPM_SINGLE("IN3R Switch", RK616_MIXINR_CTL,
RK616_MIR_F_IN3R_SFT, 1, 1),
SOC_DAPM_SINGLE("MIXINR Mux Switch", RK616_MIXINL_CTL,
SOC_DAPM_SINGLE("MIXINR Mux Switch", RK616_MIXINR_CTL,
RK616_MIR_F_MIRM_SFT, 1, 1),
};
@@ -1662,7 +1661,6 @@ static struct rk616_reg_val_typ palyback_power_down_list[] = {
};
#define RK616_CODEC_PALYBACK_POWER_DOWN_LIST_LEN ARRAY_SIZE(palyback_power_down_list)
/********** capture ********/
static struct rk616_reg_val_typ capture_power_up_list[] = {
{0x828, 0x09}, //Set for Capture pop noise
{0x83c, 0x00}, //power up
@@ -1693,22 +1691,23 @@ static int rk616_codec_power_up(int type)
int i;
if (!rk616_priv || !rk616_priv->codec) {
printk("%s : %s %s\n", __func__, rk616_priv ? "" : "rk616_priv is NULL",
rk616_priv->codec ? "" : "rk616_priv->codec is NULL");
printk("%s : rk616_priv or rk616_priv->codec is NULL\n", __func__);
return -EINVAL;
}
printk("%s\n", __func__);
printk("%s : power up %s%s\n", __func__,
type == RK616_CODEC_PALYBACK ? "playback" : "",
type == RK616_CODEC_CAPTURE ? "capture" : "");
if (type == RK616_CODEC_PALYBACK) {
DBG("rk616 codec palyback power up !\n");
for (i = 0; i < RK616_CODEC_PALYBACK_POWER_UP_LIST_LEN; i++) {
snd_soc_write(codec, palyback_power_up_list[i].reg, palyback_power_up_list[i].value);
snd_soc_write(codec, palyback_power_up_list[i].reg,
palyback_power_up_list[i].value);
}
} else if (type == RK616_CODEC_CAPTURE) {
DBG("rk616 codec capture power up !\n");
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);
snd_soc_write(codec, capture_power_up_list[i].reg,
capture_power_up_list[i].value);
}
}
@@ -1717,29 +1716,34 @@ 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;
int i;
if (!rk616_priv || !rk616_priv->codec) {
printk("%s : %s %s\n", __func__, rk616_priv ? "" : "rk616_priv is NULL",
rk616_priv->codec ? "" : "rk616_priv->codec is NULL");
printk("%s : rk616_priv or rk616_priv->codec is NULL\n", __func__);
return -EINVAL;
}
printk("%s\n", __func__);
if (rk616->playback_active <= 0 && rk616->capture_active <= 0)
type = RK616_CODEC_ALL;
printk("%s : power down %s%s%s\n", __func__,
type == RK616_CODEC_PALYBACK ? "playback" : "",
type == RK616_CODEC_CAPTURE ? "capture" : "",
type == RK616_CODEC_ALL ? "all" : "");
if (type == RK616_CODEC_CAPTURE) {
DBG("rk616 codec capture power down !\n");
for (i = 0; i < RK616_CODEC_CAPTURE_POWER_DOWN_LIST_LEN; i++) {
snd_soc_write(codec, capture_power_down_list[i].reg, capture_power_down_list[i].value);
snd_soc_write(codec, capture_power_down_list[i].reg,
capture_power_down_list[i].value);
}
} else if (type == RK616_CODEC_PALYBACK) {
DBG("rk616 codec palyback power down !\n");
for (i = 0; i < RK616_CODEC_PALYBACK_POWER_DOWN_LIST_LEN; i++) {
snd_soc_write(codec, palyback_power_down_list[i].reg, palyback_power_down_list[i].value);
snd_soc_write(codec, palyback_power_down_list[i].reg,
palyback_power_down_list[i].value);
}
} else if (type == RK616_CODEC_ALL) {
DBG("rk616 codec power down !\n");
rk616_reset(codec);
}
@@ -1748,20 +1752,21 @@ static int rk616_codec_power_down(int type)
static void rk616_codec_capture_work(struct work_struct *work)
{
DBG("%s : rk616_codec_work_capture_type = %d\n", __func__, rk616_codec_work_capture_type);
DBG("%s : rk616_codec_work_capture_type = %d\n", __func__,
rk616_codec_work_capture_type);
switch (rk616_codec_work_capture_type) {
case RK616_CODEC_WORK_POWER_DOWN:
rk616_codec_power_down(RK616_CODEC_CAPTURE);
break;
case RK616_CODEC_WORK_POWER_UP:
rk616_codec_power_up(RK616_CODEC_CAPTURE);
break;
default:
break;
}
switch (rk616_codec_work_capture_type) {
case RK616_CODEC_WORK_POWER_DOWN:
rk616_codec_power_down(RK616_CODEC_CAPTURE);
break;
case RK616_CODEC_WORK_POWER_UP:
rk616_codec_power_up(RK616_CODEC_CAPTURE);
break;
default:
break;
}
rk616_codec_work_capture_type = RK616_CODEC_WORK_NULL;
rk616_codec_work_capture_type = RK616_CODEC_WORK_NULL;
}
static int rk616_startup(struct snd_pcm_substream *substream,
@@ -1783,7 +1788,7 @@ static int rk616_startup(struct snd_pcm_substream *substream,
return -EINVAL;
}
DBG("%s : substream->stream:%s \n", __func__,
DBG("%s : substream->stream : %s \n", __func__,
playback ? "PLAYBACK":"CAPTURE");
if (playback)
@@ -1792,32 +1797,26 @@ static int rk616_startup(struct snd_pcm_substream *substream,
rk616->capture_active++;
if (playback) {
if( rk616->playback_active > 0 ){
if (!is_codec_playback_running)
rk616_codec_power_up(RK616_CODEC_PALYBACK);
else
DBG(" Warning :playback has been opened, so return! \n");
}else
DBG("playback_active <= 0, so playback can not be been opened! \n");
if (rk616->playback_active > 0) {
if (!is_codec_playback_running)
rk616_codec_power_up(RK616_CODEC_PALYBACK);
else
DBG(" Warning : playback has been opened, so return! \n");
}
} else {//capture
if( rk616->capture_active > 0) {
if (!is_codec_capture_running) {
if (rk616_codec_work_capture_type != RK616_CODEC_WORK_POWER_UP) {
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 {
rk616_codec_work_capture_type = RK616_CODEC_WORK_NULL;
DBG(" Warning :capture being closed, so interrupt the shutdown process ! \n");
}
} else { //RK616_CODEC_WORK_POWER_UP
DBG(" Warning :capture being opened , so return ! \n");
}
} else
DBG(" Warning :capture has been opened ,so return !\n");
}else
DBG("capture_active <= 0, so capture can not be been opened! \n");
if (rk616->capture_active > 0 && !is_codec_capture_running) {
if (rk616_codec_work_capture_type != RK616_CODEC_WORK_POWER_UP) {
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(" Warning : capture being closed, so interrupt the shutdown process ! \n");
rk616_codec_work_capture_type = RK616_CODEC_WORK_NULL;
}
} else {
DBG("Warning : capture being opened, so return ! \n");
}
}
}
return 0;
@@ -1851,39 +1850,36 @@ static void rk616_shutdown(struct snd_pcm_substream *substream,
rk616->capture_active--;
if (playback) {
if(rk616->playback_active <= 0){
if (is_codec_playback_running == true)
rk616_codec_power_down(RK616_CODEC_PALYBACK);
else
DBG(" Warning :playback has been closed ,so return !\n");
}else
DBG("playback_active > 0 ,so palyback can not be power down !\n");
if (rk616->playback_active <= 0) {
if (is_codec_playback_running == true)
rk616_codec_power_down(RK616_CODEC_PALYBACK);
else
DBG(" Warning : playback has been closed, so return !\n");
}
} else {//capture
if( rk616->capture_active <= 0 ){
if ((rk616_codec_work_capture_type != RK616_CODEC_WORK_POWER_DOWN) &&
(is_codec_capture_running == true)) {
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 is playback call power down, power down immediatly, because audioflinger
* already has delay 3s.
*/
if (rk616_codec_work_capture_type == RK616_CODEC_WORK_NULL) {
rk616_codec_work_capture_type = RK616_CODEC_WORK_POWER_DOWN;
queue_delayed_work(rk616_codec_workq, &capture_delayed_work,msecs_to_jiffies(3000));
} else {
rk616_codec_work_capture_type = RK616_CODEC_WORK_NULL;
DBG(" Warning :capture being opened, so interrupt the open process ! \n");
}
} else {
DBG(" Warning :capture has been closed or it being closed ,so return !\n");
}
}else
DBG("capture_active > 0 ,so capture can not be power down !\n");
if (rk616->capture_active <= 0) {
if ((rk616_codec_work_capture_type != RK616_CODEC_WORK_POWER_DOWN) &&
(is_codec_capture_running == true)) {
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 is playback call power down, power down immediatly, because audioflinger
* already has delay 3s.
*/
if (rk616_codec_work_capture_type == RK616_CODEC_WORK_NULL) {
rk616_codec_work_capture_type = RK616_CODEC_WORK_POWER_DOWN;
queue_delayed_work(rk616_codec_workq, &capture_delayed_work,msecs_to_jiffies(3000));
} else {
rk616_codec_work_capture_type = RK616_CODEC_WORK_NULL;
DBG(" Warning : capture being opened, so interrupt the open process ! \n");
}
} else {
DBG(" Warning : capture has been closed or it being closed, so return !\n");
}
}
}
}
@@ -2149,8 +2145,7 @@ void rk616_platform_shutdown(struct platform_device *pdev)
DBG("%s\n", __func__);
if (!rk616_priv || !rk616_priv->codec) {
printk("%s : %s %s\n", __func__, rk616_priv ? "" : "rk616_priv is NULL",
rk616_priv->codec ? "" : "rk616_priv->codec is NULL");
printk("%s : rk616_priv or rk616_priv->codec is NULL\n", __func__);
return;
}
@@ -2208,8 +2203,7 @@ static ssize_t rk616_proc_write(struct file *file, const char __user *buffer,
int reg, value;
if (!rk616_priv || !rk616_priv->codec) {
printk("%s : %s %s\n", __func__, rk616_priv ? "" : "rk616_priv is NULL",
rk616_priv->codec ? "" : "rk616_priv->codec is NULL");
printk("%s : rk616_priv or rk616_priv->codec is NULL\n", __func__);
return -EINVAL;
}

View File

@@ -102,6 +102,7 @@ static int rk_hifi_hw_params(struct snd_pcm_substream *substream,
/* MCLK must be 12M when HDMI is in */
if (get_hdmi_state()) {
DBG("%s : HDMI is in, do not set sys clk\n",__FUNCTION__);
return 0;
}
/* set codec DAI configuration */
@@ -181,6 +182,7 @@ static int rk_voice_hw_params(struct snd_pcm_substream *substream,
/* MCLK must be 12M when HDMI is in */
if (get_hdmi_state()) {
DBG("%s : HDMI is in, do not set sys clk\n",__FUNCTION__);
return 0;
}
/* set codec DAI configuration */