ARM: msm: dts: add external PA property to sound node.

8916 target supports external PA over secondary interface.
Add a property to inform machine driver about the external PA
present on the target add the pin control settings for
secondary MI2S interface to route to external world.

CRs-Fixed: 660843
Change-Id: Ic8b8699d7c018d8735080255e43a88da63bb98ed
Signed-off-by: Santosh Mardi <gsantosh@codeaurora.org>
This commit is contained in:
Santosh Mardi 2014-05-14 16:14:49 +05:30 committed by Aviral Gupta
parent fc6d1fe678
commit 731e20def2
6 changed files with 137 additions and 36 deletions

View file

@ -523,6 +523,9 @@ Required properties:
internal or external.
- qcom,msm-hs-micbias-type : This property is used to recognize the headset
micbias type, internal or external.
- qcom,msm-ext-pa : This property is used to inform machine driver about
the connection of external PA over secondary MI2S interface, val 0 external
PA is not there, Val 1 external PA is connected.
- qcom,msm-mbhc-hphl-swh: This property is used to distinguish headset HPHL
switch type on target typically the switch type will be normally open or
normally close, value for this property 0 for normally close and 1 for
@ -559,6 +562,7 @@ Example:
qcom,model = "msm8x16-snd-card";
qcom,msm-snd-card-id = <0>;
qcom,msm-codec-type = "internal";
qcom,msm-ext-pa = <0>;
qcom,msm-mbhc-hphl-swh = <0>;
qcom,msm-mbhc-gnd-swh = <0>;
qcom,msm-hs-micbias-type = "internal";

View file

@ -200,6 +200,7 @@
qcom,model = "msm8x16-snd-card";
qcom,msm-snd-card-id = <0>;
qcom,msm-codec-type = "internal";
qcom,msm-ext-pa = <0>;
qcom,msm-mbhc-hphl-swh = <0>;
qcom,msm-mbhc-gnd-swh = <0>;
qcom,msm-hs-micbias-type = "internal";
@ -214,9 +215,13 @@
"AMIC2", "MIC BIAS Internal2",
"AMIC3", "MIC BIAS Internal3";
pinctrl-names = "cdc_pdm_lines_act",
"cdc_pdm_lines_sus";
"cdc_pdm_lines_sus",
"cdc_ext_pa_act",
"cdc_ext_pa_sus";
pinctrl-0 = <&cdc_pdm_lines_act>;
pinctrl-1 = <&cdc_pdm_lines_sus>;
pinctrl-2 = <&cdc_ext_pa_act &cdc_ext_pa_ws_act>;
pinctrl-3 = <&cdc_ext_pa_sus &cdc_ext_pa_ws_sus>;
};
sound-9306 {

View file

@ -131,6 +131,7 @@
qcom,model = "msm8x16-snd-card-mtp";
qcom,msm-snd-card-id = <0>;
qcom,msm-codec-type = "internal";
qcom,msm-ext-pa = <0>;
qcom,msm-mbhc-hphl-swh = <0>;
qcom,msm-mbhc-gnd-swh = <0>;
qcom,msm-hs-micbias-type = "internal";

View file

@ -77,6 +77,38 @@
bias-disable;
};
};
cdc-ext-pa-lines {
qcom,pins = <&gp 113>, <&gp 114>,
<&gp 115>, <&gp 116>;
qcom,num-grp-pins = <4>;
qcom,pin-func = <1>;
label = "cdc-ext-pa-lines";
cdc_ext_pa_act: ext_pa_on {
drive-strength = <8>;
bias-pull-none;
};
cdc_ext_pa_sus: ext_pa_off {
drive-strength = <2>;
bias-disable;
};
};
cdc-ext-pa-ws-line {
qcom,pins = <&gp 110>;
qcom,num-grp-pins = <1>;
qcom,pin-func = <2>;
label = "cdc-ext-pa-ws-line";
cdc_ext_pa_ws_act: ext_pa_on {
drive-strength = <8>;
bias-pull-none;
};
cdc_ext_pa_ws_sus: ext_pa_off {
drive-strength = <2>;
bias-disable;
};
};
cross-conn-det {
qcom,pins = <&gp 120>;
qcom,num-grp-pins = <1>;

View file

@ -119,6 +119,7 @@ struct msm8x16_wcd_regulator {
struct msm8916_asoc_mach_data {
int codec_type;
int ext_pa;
int us_euro_gpio;
atomic_t mclk_rsc_ref;
atomic_t dis_work_mclk;

View file

@ -193,6 +193,8 @@ struct cdc_pdm_pinctrl_info {
struct pinctrl_state *cdc_pdm_act;
struct pinctrl_state *cross_conn_det_sus;
struct pinctrl_state *cross_conn_det_act;
struct pinctrl_state *ext_pa_sus;
struct pinctrl_state *ext_pa_act;
};
struct ext_cdc_tlmm_pinctrl_info {
@ -707,6 +709,54 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream)
}
}
static int conf_int_codec_mux(struct msm8916_asoc_mach_data *pdata)
{
int ret = 0;
int val = 0;
void __iomem *vaddr = NULL;
/*
*configure the Primary, Sec and Tert mux for Mi2S interface
* slave select to invalid state, for machine mode this
* should move to HW, I do not like to do it here
*/
vaddr = ioremap(LPASS_CSR_GP_IO_MUX_SPKR_CTL , 4);
if (!vaddr) {
pr_err("%s ioremap failure for addr %x",
__func__, LPASS_CSR_GP_IO_MUX_SPKR_CTL);
return -ENOMEM;
}
val = ioread32(vaddr);
val = val | 0x00030300;
if (pdata->ext_pa) {
/* enable sec MI2S interface to TLMM GPIO */
val = val | 0x0004007E;
pr_debug("%s: mux configuration = %x\n", __func__, val);
ret = pinctrl_select_state(pinctrl_info.pinctrl,
pinctrl_info.ext_pa_act);
if (ret < 0) {
pr_err("%s: Failed to configure the ext pa gpio's\n",
__func__);
iounmap(vaddr);
return ret;
}
}
iowrite32(val, vaddr);
iounmap(vaddr);
vaddr = ioremap(LPASS_CSR_GP_IO_MUX_MIC_CTL , 4);
if (!vaddr) {
pr_err("%s ioremap failure for addr %x",
__func__, LPASS_CSR_GP_IO_MUX_MIC_CTL);
return -ENOMEM;
}
val = ioread32(vaddr);
val = val | 0x00200000;
iowrite32(val, vaddr);
iounmap(vaddr);
return ret;
}
static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
@ -722,41 +772,10 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
substream->name, substream->stream);
if (!pdata->codec_type) {
/* configure the Primary, Sec and Tert mux for Mi2S interface
* slave select to invalid state, for machine mode this
* should move to HW, I do not like to do it here
*/
vaddr = ioremap(LPASS_CSR_GP_IO_MUX_SPKR_CTL , 4);
if (!vaddr) {
pr_err("%s ioremap failure for addr %x",
__func__, LPASS_CSR_GP_IO_MUX_SPKR_CTL);
return -ENOMEM;
}
val = ioread32(vaddr);
val = val | 0x00030300;
iowrite32(val, vaddr);
iounmap(vaddr);
vaddr = ioremap(LPASS_CSR_GP_IO_MUX_MIC_CTL , 4);
if (!vaddr) {
pr_err("%s ioremap failure for addr %x",
__func__, LPASS_CSR_GP_IO_MUX_MIC_CTL);
return -ENOMEM;
}
val = ioread32(vaddr);
iounmap(vaddr);
val = val | 0x00200000;
vaddr = ioremap(LPASS_CSR_GP_IO_MUX_MIC_CTL , 4);
if (!vaddr) {
pr_err("%s: ioremap failure for addr %x",
__func__, LPASS_CSR_GP_IO_MUX_MIC_CTL);
return -ENOMEM;
}
iowrite32(val, vaddr);
iounmap(vaddr);
ret = msm8x16_enable_codec_ext_clk(codec, 1, true);
ret = conf_int_codec_mux(pdata);
if (ret < 0) {
pr_err("%s: failed to enable mclk; ret=%d\n",
__func__, ret);
pr_err("%s: failed to conf internal codec mux\n",
__func__);
return ret;
}
ret = mi2s_clk_ctl(substream, true);
@ -765,6 +784,11 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
__func__, ret);
return ret;
}
ret = msm8x16_enable_codec_ext_clk(codec, 1, true);
if (ret < 0) {
pr_err("failed to enable mclk\n");
return ret;
}
/* Reset the CDC PDM TLMM pins to a default state */
ret = pinctrl_select_state(pinctrl_info.pinctrl,
pinctrl_info.cdc_pdm_act);
@ -788,7 +812,6 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
val = val | 0x00000002;
iowrite32(val, vaddr);
iounmap(vaddr);
vaddr = ioremap(LPASS_CSR_GP_IO_MUX_MIC_CTL , 4);
if (!vaddr) {
pr_err("%s: ioremap failure for addr %x",
@ -1774,9 +1797,11 @@ static int msm8x16_asoc_machine_probe(struct platform_device *pdev)
{
struct snd_soc_card *card;
struct msm8916_asoc_mach_data *pdata = NULL;
struct pinctrl *pinctrl;
const char *card_dev_id = "qcom,msm-snd-card-id";
const char *codec_type = "qcom,msm-codec-type";
const char *hs_micbias_type = "qcom,msm-hs-micbias-type";
const char *ext_pa = "qcom,msm-ext-pa";
const char *ptr = NULL;
const char *type = NULL;
int ret, id;
@ -1843,6 +1868,39 @@ static int msm8x16_asoc_machine_probe(struct platform_device *pdev)
card = &bear_cards[pdev->id];
dev_info(&pdev->dev, "default codec configured\n");
pdata->codec_type = 0;
ret = of_property_read_u32(pdev->dev.of_node, ext_pa, &id);
if (ret) {
dev_err(&pdev->dev,
"%s: missing %s in dt node\n",
__func__, ext_pa);
goto err;
}
pdata->ext_pa = id;
if (pdata->ext_pa) {
pinctrl = devm_pinctrl_get(&pdev->dev);
if (IS_ERR(pinctrl)) {
pr_err("%s: Unable to get pinctrl handle\n",
__func__);
return -EINVAL;
}
pinctrl_info.pinctrl = pinctrl;
/* get pinctrl handle for ext_pa */
pinctrl_info.ext_pa_sus = pinctrl_lookup_state(pinctrl,
"cdc_ext_pa_sus");
if (IS_ERR(pinctrl_info.ext_pa_sus)) {
pr_err("%s: Unable to get pinctrl disable handle\n",
__func__);
return -EINVAL;
}
/* get pinctrl handle for ext_pa */
pinctrl_info.ext_pa_act = pinctrl_lookup_state(pinctrl,
"cdc_ext_pa_act");
if (IS_ERR(pinctrl_info.ext_pa_act)) {
pr_err("%s: Unable to get pinctrl disable handle\n",
__func__);
return -EINVAL;
}
}
}
ret = of_property_read_string(pdev->dev.of_node,