mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 20:07:46 +09:00
wm8994 : add some route
This commit is contained in:
@@ -328,7 +328,7 @@ static void headset_timer_callback(unsigned long arg)
|
||||
struct rk_headset_pdata *pdata = headset->pdata;
|
||||
int i,level = 0;
|
||||
|
||||
printk("headset_timer_callback,headset->headset_status=%d\n",headset->headset_status);
|
||||
// printk("headset_timer_callback,headset->headset_status=%d\n",headset->headset_status);
|
||||
|
||||
if(headset->headset_status == HEADSET_OUT)
|
||||
{
|
||||
@@ -338,7 +338,7 @@ static void headset_timer_callback(unsigned long arg)
|
||||
#ifdef CONFIG_SND_SOC_WM8994
|
||||
if(wm8994_set_status() != 0)
|
||||
{
|
||||
printk("with wm8994 set the MICB2\n");
|
||||
// printk("wait wm8994 set the MICB2\n");
|
||||
// headset_info->headset_timer.expires = jiffies + 500;
|
||||
headset_info->headset_timer.expires = jiffies + 10;
|
||||
add_timer(&headset_info->headset_timer);
|
||||
|
||||
@@ -119,24 +119,37 @@ struct wm8958_enh_eq_cfg {
|
||||
|
||||
struct wm8994_pdata {
|
||||
int gpio_base;
|
||||
|
||||
/**
|
||||
* Default values for GPIOs if non-zero, WM8994_CONFIGURE_GPIO
|
||||
* can be used for all zero values.
|
||||
*/
|
||||
int gpio_defaults[WM8994_NUM_GPIO];
|
||||
|
||||
struct wm8994_ldo_pdata ldo[WM8994_NUM_LDO];
|
||||
|
||||
int num_drc_cfgs;
|
||||
struct wm8994_drc_cfg *drc_cfgs;
|
||||
int num_retune_mobile_cfgs;
|
||||
struct wm8994_retune_mobile_cfg *retune_mobile_cfgs;
|
||||
|
||||
/* LINEOUT can be differential or single ended */
|
||||
unsigned int lineout1_diff:1;
|
||||
unsigned int lineout2_diff:1;//do not use
|
||||
/* Common mode feedback */
|
||||
unsigned int lineout1fb:1;
|
||||
unsigned int lineout2fb:1;//do not use
|
||||
|
||||
//If an external amplifier speakers wm8994 enable>0 disable=0
|
||||
unsigned int PA_control_pin;
|
||||
char PA_iomux_name[50];
|
||||
int PA_iomux_mode;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Base IRQ number for WM8994, required for IRQs */
|
||||
int irq_base; //do not use
|
||||
|
||||
int num_drc_cfgs;
|
||||
struct wm8994_drc_cfg *drc_cfgs;
|
||||
|
||||
int num_retune_mobile_cfgs;
|
||||
struct wm8994_retune_mobile_cfg *retune_mobile_cfgs;
|
||||
|
||||
int num_mbc_cfgs;
|
||||
struct wm8958_mbc_cfg *mbc_cfgs;
|
||||
|
||||
@@ -149,34 +162,21 @@ struct wm8994_pdata {
|
||||
int num_enh_eq_cfgs;
|
||||
struct wm8958_enh_eq_cfg *enh_eq_cfgs;
|
||||
|
||||
/* LINEOUT can be differential or single ended */
|
||||
unsigned int lineout1_diff:1;
|
||||
unsigned int lineout2_diff:1;//do not use
|
||||
|
||||
/* Common mode feedback */
|
||||
unsigned int lineout1fb:1;
|
||||
unsigned int lineout2fb:1;//do not use
|
||||
|
||||
/* IRQ for microphone detection if brought out directly as a
|
||||
* signal.
|
||||
*/
|
||||
int micdet_irq;//do not use
|
||||
|
||||
/* WM8994 microphone biases: 0=0.9*AVDD1 1=0.65*AVVD1 */
|
||||
unsigned int micbias1_lvl:1;//do not use
|
||||
unsigned int micbias2_lvl:1;//do not use
|
||||
/* WM8994 microphone biases: 0=0.9*AVDD1 1=0.65*AVVD1 */
|
||||
unsigned int micbias1_lvl:1;//default 0 Do not set
|
||||
unsigned int micbias2_lvl:1;//default 0 Do not set
|
||||
|
||||
/* WM8994 jack detect threashold levels, see datasheet for values */
|
||||
unsigned int jd_scthr:2;//do not use
|
||||
unsigned int jd_thr:2;//do not use
|
||||
/* WM8994 jack detect threashold levels, see datasheet for values */
|
||||
unsigned int jd_scthr:2;//do not use
|
||||
unsigned int jd_thr:2;//do not use
|
||||
|
||||
/* WM8958 microphone bias configuration */
|
||||
int micbias[2];
|
||||
|
||||
//If an external amplifier speakers wm8994 enable>0 disable=0
|
||||
unsigned int PA_control_pin;
|
||||
char PA_iomux_name[50];
|
||||
int PA_iomux_mode;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -268,7 +268,7 @@ static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
|
||||
}
|
||||
|
||||
if (rate && rate < 3000000)
|
||||
DBG_INFO(codec->dev, "AIF%dCLK is %dHz, should be >=3MHz for optimal performance\n",
|
||||
dev_dbg(codec->dev, "AIF%dCLK is %dHz, should be >=3MHz for optimal performance\n",
|
||||
aif + 1, rate);//dev_warn
|
||||
|
||||
wm8994->aifclk[aif] = rate;
|
||||
@@ -1686,7 +1686,7 @@ static int wm8994_get_fll_config(struct fll_div *fll,
|
||||
u64 Kpart;
|
||||
unsigned int K, Ndiv, Nmod;
|
||||
|
||||
pr_debug("FLL input=%dHz, output=%dHz\n", freq_in, freq_out);
|
||||
DBG_CLK("FLL input=%dHz, output=%dHz\n", freq_in, freq_out);
|
||||
|
||||
/* Scale the input frequency down to <= 13.5MHz */
|
||||
fll->clk_ref_div = 0;
|
||||
@@ -1697,7 +1697,7 @@ static int wm8994_get_fll_config(struct fll_div *fll,
|
||||
if (fll->clk_ref_div > 3)
|
||||
return -EINVAL;
|
||||
}
|
||||
pr_debug("CLK_REF_DIV=%d, Fref=%dHz\n", fll->clk_ref_div, freq_in);
|
||||
DBG_CLK("CLK_REF_DIV=%d, Fref=%dHz\n", fll->clk_ref_div, freq_in);
|
||||
|
||||
/* Scale the output to give 90MHz<=Fvco<=100MHz */
|
||||
fll->outdiv = 3;
|
||||
@@ -1707,7 +1707,7 @@ static int wm8994_get_fll_config(struct fll_div *fll,
|
||||
return -EINVAL;
|
||||
}
|
||||
freq_out *= fll->outdiv + 1;
|
||||
pr_debug("OUTDIV=%d, Fvco=%dHz\n", fll->outdiv, freq_out);
|
||||
DBG_CLK("OUTDIV=%d, Fvco=%dHz\n", fll->outdiv, freq_out);
|
||||
|
||||
if (freq_in > 1000000) {
|
||||
fll->fll_fratio = 0;
|
||||
@@ -1724,14 +1724,14 @@ static int wm8994_get_fll_config(struct fll_div *fll,
|
||||
fll->fll_fratio = 4;
|
||||
freq_in *= 16;
|
||||
}
|
||||
pr_debug("FLL_FRATIO=%d, Fref=%dHz\n", fll->fll_fratio, freq_in);
|
||||
DBG_CLK("FLL_FRATIO=%d, Fref=%dHz\n", fll->fll_fratio, freq_in);
|
||||
|
||||
/* Now, calculate N.K */
|
||||
Ndiv = freq_out / freq_in;
|
||||
|
||||
fll->n = Ndiv;
|
||||
Nmod = freq_out % freq_in;
|
||||
pr_debug("Nmod=%d\n", Nmod);
|
||||
DBG_CLK("Nmod=%d\n", Nmod);
|
||||
|
||||
/* Calculate fractional part - scale up so we can round. */
|
||||
Kpart = FIXED_FLL_SIZE * (long long)Nmod;
|
||||
@@ -1746,7 +1746,7 @@ static int wm8994_get_fll_config(struct fll_div *fll,
|
||||
/* Move down to proper range now rounding is done */
|
||||
fll->k = K / 10;
|
||||
|
||||
pr_debug("N=%x K=%x\n", fll->n, fll->k);
|
||||
DBG_CLK("N=%x K=%x\n", fll->n, fll->k);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -92,8 +92,7 @@ static int rk29_aif1_hw_params(struct snd_pcm_substream *substream,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
// DBG("Enter:%s, %d, rate=%d,pll_out = %d\n",__FUNCTION__,__LINE__,params_rate(params),pll_out);
|
||||
#if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE)
|
||||
// DBG("Enter:%s, %d, rate=%d,pll_out = %d\n",__FUNCTION__,__LINE__,params_rate(params),pll_out);
|
||||
general_pll=clk_get(NULL, "general_pll");
|
||||
if(clk_get_rate(general_pll)>260000000)
|
||||
{
|
||||
@@ -112,9 +111,7 @@ static int rk29_aif1_hw_params(struct snd_pcm_substream *substream,
|
||||
div_mclk=0;
|
||||
}
|
||||
|
||||
DBG("func is%s,gpll=%ld,pll_out=%d,div_mclk=%d\n",
|
||||
__FUNCTION__,clk_get_rate(general_pll),pll_out,div_mclk);
|
||||
|
||||
DBG("func is%s,gpll=%ld,pll_out=%d,div_mclk=%d\n",__FUNCTION__,clk_get_rate(general_pll),pll_out,div_mclk);
|
||||
ret = snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0);
|
||||
if(ret < 0)
|
||||
{
|
||||
@@ -152,9 +149,6 @@ static int rk29_aif1_hw_params(struct snd_pcm_substream *substream,
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#elif defined (CONFIG_SND_RK29_CODEC_SOC_MASTER)
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -255,82 +249,99 @@ static int rk29_aif2_hw_params(struct snd_pcm_substream *substream,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rk29_aif3_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||
unsigned int pll_out = 0;
|
||||
// int div_bclk,div_mclk;
|
||||
int ret;
|
||||
// struct clk *general_pll;
|
||||
|
||||
static const struct snd_soc_dapm_widget rk29_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_SPK("Ext Left Spk", NULL),
|
||||
SND_SOC_DAPM_SPK("Ext Right Spk", NULL),
|
||||
SND_SOC_DAPM_SPK("Ext Rcv", NULL),
|
||||
SND_SOC_DAPM_HP("Headset Stereophone", NULL),
|
||||
SND_SOC_DAPM_MIC("Headset Mic", NULL),
|
||||
SND_SOC_DAPM_MIC("Main Mic", NULL),
|
||||
SND_SOC_DAPM_MIC("2nd Mic", NULL),
|
||||
// SND_SOC_DAPM_LINE("Radio In", NULL),
|
||||
SND_SOC_DAPM_LINE("Line In", NULL),
|
||||
SND_SOC_DAPM_LINE("Line Out", NULL),
|
||||
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route rk29_dapm_routes[] = {
|
||||
{"Ext Left Spk", NULL, "SPKOUTLP"},
|
||||
{"Ext Left Spk", NULL, "SPKOUTLN"},
|
||||
|
||||
{"Ext Right Spk", NULL, "SPKOUTRP"},
|
||||
{"Ext Right Spk", NULL, "SPKOUTRN"},
|
||||
|
||||
{"Ext Rcv", NULL, "HPOUT2N"},
|
||||
{"Ext Rcv", NULL, "HPOUT2P"},
|
||||
|
||||
{"Headset Stereophone", NULL, "HPOUT1L"},
|
||||
{"Headset Stereophone", NULL, "HPOUT1R"},
|
||||
|
||||
{"IN1LN", NULL, "Headset Mic"},
|
||||
{"IN1LP", NULL, "Headset Mic"},
|
||||
|
||||
{"IN1LN", NULL, "2nd Mic"},
|
||||
{"IN1LP", NULL, "2nd Mic"},
|
||||
|
||||
{"IN1RN", NULL, "Main Mic"},
|
||||
{"IN1RP", NULL, "Main Mic"},
|
||||
|
||||
// {"IN2LN", NULL, "Radio In"},
|
||||
// {"IN2RN", NULL, "Radio In"},
|
||||
|
||||
{"IN2LP:VXRN", NULL, "Line In"},
|
||||
{"IN2RP:VXRP", NULL, "Line In"},
|
||||
|
||||
{"Line Out", NULL, "LINEOUT1N"},
|
||||
{"Line Out", NULL, "LINEOUT1P"},
|
||||
|
||||
};
|
||||
|
||||
static int rk29_wm8994_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct snd_soc_dapm_context *dapm = &codec->dapm;
|
||||
// int ret;
|
||||
DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
|
||||
|
||||
/* set codec DAI configuration */
|
||||
ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
|
||||
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
|
||||
DBG("Set codec_dai master\n");
|
||||
/* add goni specific widgets */
|
||||
snd_soc_dapm_new_controls(dapm, rk29_dapm_widgets,
|
||||
ARRAY_SIZE(rk29_dapm_widgets));
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
/* set up goni specific audio routes */
|
||||
snd_soc_dapm_add_routes(dapm, rk29_dapm_routes,
|
||||
ARRAY_SIZE(rk29_dapm_routes));
|
||||
|
||||
switch(params_rate(params)) {
|
||||
case 8000:
|
||||
case 16000:
|
||||
case 24000:
|
||||
case 32000:
|
||||
case 48000:
|
||||
pll_out = 12288000;
|
||||
break;
|
||||
case 11025:
|
||||
case 22050:
|
||||
case 44100:
|
||||
pll_out = 11289600;
|
||||
break;
|
||||
default:
|
||||
DBG("Enter:%s, %d, Error rate=%d\n",__FUNCTION__,__LINE__,params_rate(params));
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
/* set endpoints to not connected */
|
||||
// snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN");
|
||||
// snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP");
|
||||
snd_soc_dapm_nc_pin(dapm, "IN2LN");
|
||||
snd_soc_dapm_nc_pin(dapm, "IN2RN");
|
||||
// snd_soc_dapm_nc_pin(dapm, "LINEOUT1N");
|
||||
// snd_soc_dapm_nc_pin(dapm, "LINEOUT1P");
|
||||
snd_soc_dapm_nc_pin(dapm, "LINEOUT2N");
|
||||
snd_soc_dapm_nc_pin(dapm, "LINEOUT2P");
|
||||
|
||||
DBG("Enter:%s, %d, rate=%d\n",__FUNCTION__,__LINE__,params_rate(params));
|
||||
snd_soc_dapm_sync(dapm);
|
||||
|
||||
ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK1, pll_out, 0);
|
||||
if (ret < 0) {
|
||||
DBG("rk29_hw_params_wm8994:failed to set the sysclk for codec side\n");
|
||||
/* Headset jack detection */
|
||||
/* ret = snd_soc_jack_new(codec, "Headset Jack",
|
||||
SND_JACK_HEADSET | SND_JACK_MECHANICAL | SND_JACK_AVOUT,
|
||||
&jack);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0);
|
||||
|
||||
#if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE)
|
||||
snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_BCLK, (pll_out/4)/params_rate(params)-1);
|
||||
snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_MCLK, 3);
|
||||
#endif
|
||||
ret = snd_soc_jack_add_pins(&jack, ARRAY_SIZE(jack_pins), jack_pins);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = snd_soc_jack_add_gpios(&jack, ARRAY_SIZE(jack_gpios), jack_gpios);
|
||||
if (ret)
|
||||
return ret;
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
static const struct snd_soc_dapm_widget rk2818_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_LINE("Audio Out", NULL),
|
||||
SND_SOC_DAPM_LINE("Line in", NULL),
|
||||
SND_SOC_DAPM_MIC("Micn", NULL),
|
||||
SND_SOC_DAPM_MIC("Micp", NULL),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route audio_map[]= {
|
||||
|
||||
{"Audio Out", NULL, "HP_L"},
|
||||
{"Audio Out", NULL, "HP_R"},
|
||||
{"Line in", NULL, "RINPUT1"},
|
||||
{"Line in", NULL, "LINPUT1"},
|
||||
{"Micn", NULL, "RINPUT2"},
|
||||
{"Micp", NULL, "LINPUT2"},
|
||||
};
|
||||
*/
|
||||
|
||||
static struct snd_soc_ops rk29_aif1_ops = {
|
||||
.hw_params = rk29_aif1_hw_params,
|
||||
@@ -340,10 +351,6 @@ static struct snd_soc_ops rk29_aif2_ops = {
|
||||
.hw_params = rk29_aif2_hw_params,
|
||||
};
|
||||
|
||||
static struct snd_soc_ops rk29_aif3_ops = {
|
||||
.hw_params = rk29_aif3_hw_params,
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_driver voice_dai = {
|
||||
.name = "rk29-voice-dai",
|
||||
.id = 0,
|
||||
@@ -372,6 +379,7 @@ static struct snd_soc_dai_link rk29_dai[] = {
|
||||
#endif
|
||||
.codec_dai_name = "wm8994-aif1",
|
||||
.ops = &rk29_aif1_ops,
|
||||
.init = rk29_wm8994_init,
|
||||
},
|
||||
{
|
||||
.name = "WM8994 I2S2",
|
||||
@@ -386,21 +394,6 @@ static struct snd_soc_dai_link rk29_dai[] = {
|
||||
.codec_dai_name = "wm8994-aif2",
|
||||
.ops = &rk29_aif2_ops,
|
||||
},
|
||||
|
||||
{
|
||||
.name = "WM8994 I2S3",
|
||||
.stream_name = "WM8994 PCM",
|
||||
.codec_name = "wm8994-codec",
|
||||
.platform_name = "rockchip-audio",
|
||||
#if defined(CONFIG_SND_RK29_SOC_I2S_8CH)
|
||||
.cpu_dai_name = "rk29_i2s.0",
|
||||
#elif defined(CONFIG_SND_RK29_SOC_I2S_2CH)
|
||||
.cpu_dai_name = "rk29_i2s.1",
|
||||
#endif
|
||||
.codec_dai_name = "wm8994-aif3",
|
||||
.ops = &rk29_aif3_ops,
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
static struct snd_soc_card snd_soc_card_rk29 = {
|
||||
|
||||
Reference in New Issue
Block a user