mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 04:10:18 +09:00
rk616 codec:Do not change mclk when HDMI is in and correct format
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user